JVM内存结构

JVM内存结构

公有部分

线程共享部分包括 Java 堆、方法区及常量池

Java堆是JVM划分出来的一块区域,专用于Java实例对象的内存配置,几乎所有实例对象都会在这里进行内存的分配。有些时候小对象会直接在栈上进行分配。

年轻代与老年代

Java堆分为Old和Young两个区域,Young区还进一步划分为Eden、From Survivor 0 、To Survivor 1区。

一个对象优先分配在Young的Eden区,等Eden区内存不够时,JVM会启动GC。此时Eden区中没有被引用的对象就会被回收,而一些存活时间较长的对象则进入到Old区。在 JVM 中有一个名为 -XX:MaxTenuringThreshold 的参数专门用来设置晋升到老年代所需要经历的 GC 次数,即在年轻代的对象经过了指定次数的 GC 后,将在下次 GC 时进入老年代。

Java堆分区域意义
虚拟机中的对象必然会存在存活时间长的对象,也有存活时间短的对象。如果将其混在一起,那么因为存活时间短的对象很多,势必导致较为频繁的GC。而GC就会把所有内存都进行扫描,但其实有一部分对象存活时间是很长的,不需要浪费时间进行扫描。因为为了提高垃圾回收效率,分区就理所当然了。

默认的虚拟机配置,Eden:from:to = 8:1:1

方法区

方法区是指存储Java类字节码数据的一块区域,它存储了每一个类的信息,例如运行时常量池、字段和方法数据、构造方法等。常量池其实是存放在方法区中的,但《Java虚拟机规范》将常量池和方法区放在同一个等级上。

方法区在不同版本的虚拟机有不同的表现形式,例如在1.7的Hotspot中,方法区称为永久代(Perm Space),而1.8中则被称之为MetaSpace。

常量池

存放于方法区中。

私有部分

Java 堆以及方法区的数据是共享的,但是有一些部分则是线程私有的。线程私有部分可以分为:PC 寄存器、Java 虚拟机栈、本地方法栈三大部分。

PC寄存器

PC 寄存器,顾名思义 Program Counter 寄存器,指的是保存线程当前正在执行的方法。如果这个方法不是 native 方法,那么 PC 寄存器就保存 Java 虚拟机正在执行的字节码指令地址。如果是 native 方法,那么 PC 寄存器保存的值是 undefined。任意时刻,一条 Java 虚拟机线程只会执行一个方法的代码,而这个被线程执行的方法称为该线程的当前方法,其地址被存在 PC 寄存器中。

Java虚拟机栈

虚拟机栈与线程同时创建,用来存储栈帧,即存储局部变量与一些过程结果的地方。栈帧存储的数据包括:局部变量表、操作数栈。

本地方法栈

支持native方法

总结

一个Java文件加载到内存中,Java的类信息就会存储在方法区中。如果创建对象,那么对象数据就会存放在Java堆中。如果调用方法,就会用到PC寄存器、Java虚拟机栈、本地方法栈等结构。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享