JVM内存结构与Java内存模型
JVM的内存结构大概分为:
- 堆(Heap):线程共享。所有的对象实例以及数组都要在堆上分配。垃圾回收器主要管理的对象。堆内存是JVM中最大的一块。
- 方法区(Method Area):线程共享。存储类信息、常量、静态变量、即时编译器编译后的代码。
- 方法栈(JVM Stack):线程私有。存储局部变量表、操作栈、动态链接、方法出口,对象指针。
- 本地方法栈(Native Method Stack):线程私有。为虚拟机使用到的Native 方法服务。如Java使用c或者c++编写的接口服务时,代码在此区运行。
- 程序计数器(Program Counter Register):线程私有。有些文章也翻译成PC寄存器(PC Register),同一个东西。它可以看作是当前线程所执行的字节码的行号指示器。指向下一条要执行的指令。
GC堆内存结构:
首先,GC堆内存分为三部分:新生代,老年代,永久代。 新生代做复制清理、老年代做的是标记整理、标记清除。默认状态 Eden:S0:S1:Old = 8:1:1:20
,也就是新生代与老年代比例为 1:2,由于S0和S1总是互相替换,因此新生代实际只会使用9/10的空间。设置-XX:SurvivorRatio=N
表示Eden区会占用新生代N/N+2
的空间。
控制参数:
-Xms设置堆的最小空间大小。
-Xmx设置堆的最大空间大小。
-XX:NewSize设置新生代最小空间大小。
-XX:MaxNewSize设置新生代最大空间大小。
-XX:PermSize设置永久代最小空间大小。
-XX:MaxPermSize设置永久代最大空间大小。
-Xss设置每个线程的堆栈大小。
引用计数:存在循环引用问题
可达性分析:从GC root 开始搜索,,搜索所走过的路径称为引用链。GC Roots包括:
- 虚拟机栈中引用的对象。
- 方法区中类静态属性实体引用的对象。
- 方法区中常量引用的对象。
- 本地方法栈中JNI引用的对象。
垃圾回收算法:
复制算法:通常为年轻代使用的,将内存分为相等的两块,每次只使用其中一块。当这一块的内存用完了,就将存活的对象复制到另一块,然后将使用过的空间整体清理掉。(简单高效,费内存,对长生命周期的对象不太友好)
标记-清除法:最基础的收集方法,先标记出需要回收的对象,标记完成后,统一回收。(CMS三色标记,使用可达性算法)
GC与非GC时间耗时比例超过了GCTimeRatio的限制也会引发OOM,调优诸如通过NewRatio控制新生代老年代比例,通过MaxTenuringThreshold控制进入老年前生存次数等。
Java Object Laout(JOL):Java对象内存布局
org.openjdk.jol 查看内存布局的工具
ClassLayout.parseInstance(o).toPrintable();
字节数被8整除
markword (8字节 64位 记录锁信息,记录GC信息,记录 Identity HashCode)
class pointer 类指针
instance data
padding (需要被8整除)
给对象加锁,就是修改markword的值
对象分代年龄只占4位,G1,PS,PO等默认最高15
CMS 默认分代最多6
CMS在进行并发标记清除的时候,可能由于对象分配过快,导致再次出发FullGC。CMS通过将三色标记过程中发生引用变更的对象加入标记栈,通过remark过程重新扫描,防止漏标记。
G1,ZGS等没有分代
G1通过将整个内存分成小块,每个小块可能是年轻代,也可能是老年代。G1在GC开始时,对对象标记快照,只要开始GC时,是存活额,就认为其是存活的。
锁升级步骤(锁升级会stw)
偏向锁(用户态 CAS 当前线程指针)–>轻量级锁(用户态 CAS)–>重量级锁(内核态)
TLAB(Thread Local Allocation Buffer)
TLAB是为了避免对象在年轻代的内存分配时的竞争而设计的,大部分对象都在新生代中分带,但是线程太多,会导致分配内存的指针成征用热点。因此为每个线程分配一个单独的申请区域。该区域只允许一个线程申请空间,但是所有线程都可以访问。TLAB只能分配小对象,大对象还是需要在共享区域分配。
PLAB
类似TLAB,是为了避免YGC时,大量对象通过多线程从新生代晋升到老年代,会产生老年代的内存指针竞争。
参考:
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 using1174@foxmail.com
文章标题: JVM内存结构与Java内存模型
文章字数: 1,230
本文作者: Jun
发布时间: 2019-05-29, 19:14:00
最后更新: 2022-04-25, 14:50:11
原始链接: http://yoursite.com/2019/05/29/JVM内存结构与Java内存模型/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。