jvm

JVM——运行时数据区

2021-06-14  本文已影响0人  小波同学

JVM的简化架构

运行时数据区

包括:程序计数器(PC寄存器)、Java虚拟机栈、Java堆、方法区、运行时常量池、本地方法栈等等。

PC 寄存器,也叫程序计数器

虚拟机栈

Java堆

方法区

运行时常量池

本地方法栈

栈、堆、方法区交互关系

栈、堆、方法区交互关系

Java堆内存模型和分配

Java堆的结构

Java堆的结构

堆是JVM内存占用最大,管理最复杂的一个区域。其唯一的用途就是存放对象实例:所有的对象实例及数组都在堆上进行分配。1.7后,字符串常量池从永久代中剥离出来,存放在堆中。堆有自己进一步的内存分块划分,按照GC分代收集角度的划分。

对象的内存布局

对象在内存中存储的布局(这里以HotSpot虚拟机为例说明),分为:对象头、实例数据和对齐填充。

对象头包含两个部分:
实例数据:
对齐填充:

这部分不一定存在,也没什么特别意义,仅仅是占位符。这是因为HotSpot要求对象起始地址都是8字节的整数倍,如果不是就对齐。

对象的访问定位

通过句柄访问对象

各自的优势

trace跟踪参数

GC日志格式

Java堆的参数

Java栈的参数

元空间的参数

内存分配与回收策略

内存分配,主要就是堆内存分配, (也有可能经过JIT编译后被拆散为标量类型并间接的栈上分配),主要分配在新生代的eden上,如果启动了本地线程分配缓冲,将按线程优先在TLAB上分配,少数情况下可能直接分配在老年代中。分配的规则不是百分百固定的。取决于垃圾收集器的组合和虚拟机的参数设置

对象优先在Eden分配

大多数情况下,对象在新生代eden区中分配,当Eden 区没有足够空间进行分配时,发起一次 minor GC。虚拟机提供-XX:+PrintGCDetails 这个收集器日志参数,来打印日志收集日志。

大对象直接进老年代

大对象:需要大量连续内存空间的java对象 如 很长的字符串和数组。-XX:PretenureSizeThreshold 设置 大于这个值的对象直接分配在老年代

长期存活的对象进入老年代

-XX:MaxTenuringThreshold 设置年龄大于多少的对象进入老年代 默认 15 对象在 survivor中每熬过一次 minorGC年龄加一岁

动态对象年龄判断

当survivor 空间中相同年龄所有对象大小综合大于survivor 空间的一半 ,年龄大于或等于该年龄的对象可以提前进入老年代,无需等到年龄达到。

空间分配担保

发生minor GC 前虚拟机 计算老年代的连续空间是否大于新生代对象总大小或历次晋升的平均大小,是就会进行 MinorGC 否则进行FullGC

参考:
https://www.cnblogs.com/lsgxeva/p/10231201.html

https://www.cnblogs.com/lfs2640666960/p/8522588.html

https://blog.csdn.net/u011080472/article/details/51321769

https://blog.csdn.net/iva_brother/article/details/87886525

http://blog.itpub.net/69906029/viewspace-2654005/

https://blog.csdn.net/zhangxm_qz/article/details/88576660

上一篇 下一篇

猜你喜欢

热点阅读