JVM内存结构

JVM内存结构 - 实现

JVM内存结构
JVM内存结构.png
Survivor区

分为大小相等的2个区S0(from)和S1(to),在同一个时间点上只有一个区有数据;

非堆区(Metaspace)

存放Class、Package、Method、Field、字节码、常量池、符号引用等;

CCS(压缩类空间)

只有启动短直针的时候才会存在;在堆中分配的每个对象,都存在一个指向自己的Class的指针,在64位虚拟机中每个指针是64位的,如果使用短直针(32位),其指向的class文件就会存储在CCS中;

CodeCache

存放JIT编译后的代码和JNI的native代码;

运行时数据区 - 规范

JVM内存结构
JVM运行时数据区.png
程序计数器

JVM支持多线程同时执行,每一个线程都有自己的PC Register,线程正在执行的方法叫当前方法,如果是Java代码,PC Register中存放的就是当前正在执行的指令的地址,如果是C代码,则为空;

虚拟机栈

Java虚拟机栈(Java Virtual Machine Stacks)是线程私有的,它的生命周期与线程相同;虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行的同时会创建一个栈帧,用于存储局部变量表,操作数栈,动态链接,方法出口等信息;每一个方法从调用到执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程;

Java堆(Java Heap)是Java虚拟机所管理的内存中最大的一块;堆是被所有线程共享的一块内存区域,在虚拟机启动时创建;此内存区的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存;Java堆可以处在物理上不连续的内存空间中,只要逻辑上是连续的即可;

方法区

方法区和Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据;虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫做Non-Heap(非堆),目的是与Java堆区分开来;

常量池(方法区的一部分)

运行时常量池(Runtime Constant Pool)是方法区的一部分;Class文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池(Constant Pool Table),用于存放编译期生成的各种字面量和符号引用,这部分信息将在类加载后进入方法区的运行时常量池中;

本地方法栈

本地方法栈(Native Method Stack)与虚拟机栈发挥的作用非常类似,它们之间的区别是:虚拟机栈为Java方法(字节码)服务,而本地方法栈则为虚拟机使用到的Native方法服务;

常用参数

  • -Xms -Xmx
    堆的最小最大值;
  • -XX:NewSize -XX:MaxNewSize
    新生代大小;
  • -XX:NewRatio
    Yong区和Old区的比例;
  • -XX:SurvivorRatio
    Survivor区和Eden区的比例;
  • -XX:MetaspaceSize -XX:MaxMetaspaceSize
    Metaspace的大小,一般只调它,它调大,CCS和CodeCache都会跟着大;
  • -XX:+UseCompressedClassPointers
    是否启用压缩类指针;
  • -XX:CompressedClassSpaceSize
    CCS的大小,默认1G;
  • -XX:InitialCodeCacheSize
    CodeCache的初始大小;
  • -XX:ReversedCodeCacheSize
    CodeCache的最大值;