JVM内存结构与Java内存模型

Java内存模型

JVM内存结构
JVM的内存结构大概分为:

  • 堆(Heap):线程共享。所有的对象实例以及数组都要在堆上分配。垃圾回收器主要管理的对象。堆内存是JVM中最大的一块。
  • 方法区(Method Area):线程共享。存储类信息、常量、静态变量、即时编译器编译后的代码。
  • 方法栈(JVM Stack):线程私有。存储局部变量表、操作栈、动态链接、方法出口,对象指针。
  • 本地方法栈(Native Method Stack):线程私有。为虚拟机使用到的Native 方法服务。如Java使用c或者c++编写的接口服务时,代码在此区运行。
  • 程序计数器(Program Counter Register):线程私有。有些文章也翻译成PC寄存器(PC Register),同一个东西。它可以看作是当前线程所执行的字节码的行号指示器。指向下一条要执行的指令。

JVM运行时数据区段

GC堆内存结构:
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对象内存布局

JOL
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时,大量对象通过多线程从新生代晋升到老年代,会产生老年代的内存指针竞争。

参考:

从实际案例聊聊Java应用的GC优化_美团技术团队

深入理解JVM的内存结构及GC机制_掘金

JVM内存结构和Java内存模型

Java面试高级

G1与CMS


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 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" 转载请保留原文链接及作者。

目录
×

喜欢就点赞,疼爱就打赏