Java学习之【深入理解Java虚拟机---Java内存区域】

 2019-12-22 11:07  阅读(931)
文章分类:JVM
  1. 运行时数据区域

    1. 定义:简单来说就是Java程序运行时会把内存划分为若干个数据区域,这些区域被称为运行时数据区域。每个区域都有各自的用途,以及创建和销毁的时间。
    2. 数据区域划分:程序计数器,虚拟机栈,本地方法栈,堆,方法区。下面一一介绍各个数据区域的用途。
    3. 2019120001585\_1.png
  2. 程序计数器

    1. 可以简单理解为在你执行代码时,解释器通过程序计数器的值来选取下一条需要执行的代码。(在虚拟机中被称为字节码指令)
    2. 程序计数器在内存中属于线程隔离的数据区。相当于就是线程私有内存,每个线程都拥有自己的程序计数器,否则Java虚拟机在多线程切换时将无法恢复到之前正确的执行位置上。比如有两个线程,线程A的程序计数器的值为5,这个时候线程B抢到CPU资源后把程序计数器变成了7,如果这个时候线程不是私有的而是共享的那线程A下一次执行的时候将会获取到线程B修改后的程序计数器上的值,也就会执行位置7上面的代码。
  3. Java虚拟机栈

    1. 虚拟机栈也属于线程私有的。它描述的是Java方法执行的内存模型:每个方法在执行时都会创建一个栈帧。
    2. 栈帧也就是一个数据结构,主要用于存储局部变量表(也就是我们在方法内部定义的各种基本数据类型,对象引用。它所需要的内存空间将在编译期间完成分配),操作数栈(可以理解为一个为局部变量所提供的临时存储区域,在调用方法时,也用来准备调用方法的参数以及接收方法返回结果),动态链接,方法出口等信息。
  4. 本地方法栈

    1. 本地方法栈和虚拟机栈还有程序计数器都属于线程私有的。它和虚拟机栈的所用极其相似。唯一的区别就是虚拟机栈执行的是Java的方法,而本地方法栈执行的是使用Native标识符标识的方法,在Java中被Native标识的方法也称为本地方法。
  5. Java堆

    1. 该内存区域唯一的目的就是存放对象实例,每当我们用关键字new一个对象时,该对象的实例将会在这个内存区域内分配内存。
  6. 方法区

    1. 我们都知道Java类以及类的常量和静态变量都是在第一次加载类的时候加载的,这个时候这些数据都将被存储在方法区内。除了这些它还会存储一些类的信息,以及即时编译器编译后的代码等数据。简单来说方法区存储的都是一些一次性加载的数据,像编译后的代码,常量,静态变量这些都是只加载一次的数据。
  7. 运行时常量池

    1. 运行时常量池是方法区里面的一部分,一个类我们大致可以划分为类的版本,字段,方法,接口。字段我们又可以分为常量和变量,变量我们知道是存在Java堆里的,那常量的话就是存在运行时常量池里。在常量中又有字面量和符号引用的区分,字面量的意思就是直接代表一个值。举个例子:int count = 10;(// 10就是一个数字字面量)。String name=”zhangsan”(//zhangsan就是一个字符串字面量)。有时候我们经常会看到符号引用和直接引用的概念。一个java类编译成class文件时,java类并不知道引用类的实际内存地址,因此这个时候只能先用一个符号来替代,这个就叫符号引用。当类加载器加载了引用类时,这个时候就能通过虚拟机获取到引用类的实际内存地址了,因此这个时候就可以将符号替换成引用类的实际地址了,这样也就是直接引用了。
  8. 总结

    1. Java整个程序的运行时内存分布对于我们来说最关心的就是三大块。虚拟机栈,方法区和Java堆。在运行时当一个类第一次被加载时,类的常量,静态变量等一次性加载的信息将会存储到方法区内。当每次用关键字new了一个对象实例时,这个时候将会把该实例分配到java堆中,使用时也从java堆中获取。new完对象后将要调用方法时将会到虚拟机栈里创建一个栈帧,每一个方法从调用到执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。
点赞(1)
版权归原创作者所有,任何形式转载请联系作者; Java 技术驿站 >> Java学习之【深入理解Java虚拟机---Java内存区域】

相关推荐