JVM - 内存结构
2020-04-02 本文已影响0人
万福来
JVM - 内存结构
image.png方法区和堆是所有线程共享的内存区域,java栈、本地方法栈和程序计数器是运行时线程私有的内存区域
- Java堆(Heap):虚拟机启动时创建,所有线程共享,可以存放对象实例;
- 方法区:所有线程共享,主要存储jvm加载的类信息、常量、静态变量和即时编译后的代码;
- 程序计数器:用来存储当前线程所执行的字节码行号数据。
- Java栈:线程私有的,用于存储局部变量,操作栈。动态链接、方法出口等数据;
- 本地方法栈:与Java栈类似,主要服务本地Native方法。
Java对象分配规则
- 如果JVM开启了逃逸分析,并且新分配的对象引用如果没有发生方法逃逸和线程逃逸,则优先尝试在线程栈内存进行分配;
- 如果无法分配还可以在线程的TLAB区域进行分配,默认大小不超过64b;
- 对象则分配在Eden区,如果eden区空间不足,则先执行一次young gc;
- 大对象可以直接分配在老年代;可以避免在年轻代来回复制;
- 长期存活的对象晋升到老年代,可以根据对象经历过的younggc次数计算对象的年龄,经历一次gc后仍然存活的对象复制到from区,每经历一次gc然后在复制到to区,两个区域来回复制,直到对象的年龄达到晋升阈值后复制到老年代;
- 如果from或to区中相同年龄的对象大小的总和大于目标复制区域时,年龄大于或等于该年龄的对象可以直接复制到老年代;
- 空间分配担保。每次进行young GC时,JVM会计算Survivor区移至老年区的对象的平均大小,如果这个值大于老年区的剩余值大小则进行一次Full GC,如果小于检查HandlePromotionFailure设置,如果true则只进行young GC,如果false则进行Full GC。