一、线程共享内存区
包括堆区。运行时常量池和方法区
二、java堆区
实际的空间中不连续,GC的重点回收领域。java 对象的生命周期有长有短,故应采用不同的垃圾回收策略。故java堆区细分的话。可以划分为新生代(YoungGen)和老年代(OldGen)。新生代又划分为Eden空间。From Survivor空间和To Survivor空间。
jdk配置文件中可修改相应的参数: “-Xmx”表示堆的起始内存。“-Xms”表示堆区的最大内存。
三、方法区
存储每一个java类的结构信息,比如:运行时常量池、字段和方法数据、构造方法和普通方法的字节码内容以及类、实例、接口初始化时需要用到的特殊方法等数据。方法区逻辑上独立,实际属于堆区的一部分。但是它不像堆区那样频繁被调用。还可以显示指定是否需要在程序运行时回收,所以它被称为永久代。若无显式要求,GC的回收目标仅针对方法区中的常量池和类型卸载。
四、运行时常量池
将类或者接口载入JVM后,就会创建阈值对应的运行时常量池。
五、线程私有内存区
包括java栈、本地方法栈、PC寄存器(计数器)
六、PC寄存器
若当前线程正在运行一个java方法,那么PC寄存器就会存储正在执行的字节码指令地址。反之若是native方法。则存储的值为空(undefined)。
七、java栈
也成为java虚拟机栈,java栈用于存储栈帧,栈帧中存储的是局部变量表。操作数栈以及方法出口等信息。
八、本地方法栈
用于支持本地方法。
九、内存分配原理
当语法层面使用new关键字创建一个java对象时,JVM首先检查这个new 指令的参数能否在常量池中定位到一个类的符号引用,然后检查这个符号引用相对应的类是否已经成功经历过加载、解析和初始化等步骤。当类完成加载步骤后,就可以完全确定创建对象实例时所需要的内存大小。接下来JVM会对其进行内存分配,以存储所生成的对象实例。
TLAB (Thread Local Allocation 本地线程分配缓冲区)
十、逃逸分析与栈上分配
逃逸分析具体目标是分析出对象的作用域,一个对象被定义在方法体内部后,它的受访权限仅限于方法体内,一旦其引用被外部成员引用后,该对象就发生逃逸,反之,该对象并没有被任何外部成员引用时,JVM为其在栈帧中分配内存空间。