JVM内存模型和GC的解析

jvm内存模型
  • JVM调优是调整:方法区和堆(主要是堆)
  • 栈管运行,堆管存储
  • 堆和方法区是所有线程共享的内存区域;栈和程序计数器是每个线程私有的内存区域。
    注:由于栈是每个线程私有的,栈空间是每个线程的运行内存
  • 运行时数据区也就是我们的JVM内存模型区域。JVM在运行程序时会将他拥有的内存 逻辑性的划分,让每部分内存做它该做的事情。

类加载器(class loader):

加载 .class文件,生成类模板。(只负责类的加载,能不能运行要看Execution Engine执行引擎)

  • 类加载器分为:
    • 启动类加载器
    • 扩展类加载器
    • 应用类加载器

双亲委派机制:往上抛,上面的如果可以加载,就用上面的

本地方法接口(Native Interface):调用C/C++的本地库
本地方法栈(Native Method Stack):让执行引擎加载本地方法
程序计数器:用来存储指向下一条指令的地址,也即将要执行的指令代码
执行引擎(Execution Engine):负责解释命令,提交操作系统执行


栈(stack):

  • 每个线程都有一个私有的栈,随着线程的创建而创建
  • 栈存储8种基本数据类型 + 引用变量(存储堆中地址)+ 实例方法
  • 压栈,先进后出
  • java.lang.StackOverFlowError 栈溢出异常(创建的引用太多,或死循环)

方法区(Method Area):

存储 静态变量,常量,类模板(构造方法/接口定义)

堆(heap)

分为三个区域

  • 新生代
    • 伊甸园区
    • 幸存0区
    • 幸存1区
  • 老年代
  • 永久代
  1. 新生代 + 老年代 = 实际堆内存
  2. java1.7永久代 = 方法区(存放静态变量,常量,类模板);
    java1.8永久代 = 方法区(存放静态变量,常量)+本地内存-元空间(存放类模板), 改善了之前依赖的jar包太多,加载的类模板太多,启动项目时会出现永久区OOM:PermGen space的情况
  3. 空间占用
    · 新生代占堆空间的1/3,其中伊甸园区:From区:To区 = 8:1:1
    · 老年代占堆空间的2/3




GC(Garbage Collection)

分代垃圾收集算法:新生代和老年代的收集算法不同

  • 频繁收集新生代:minorGC 轻量级GC—使用复制算法
  • 较少收集老年代:majorGC,也叫fullGC:使用标记清除算法,标记清除压缩算法
  • 基本不动永久代

majorGC速度比minorGC慢10倍以上

GC的四种回收算法:

  1. 引用计数法(native源码中有,但不使用):维护一个kv结构,key为变量,v为引用次数,每次清理v=0的变量;
    · 缺点:变量互相引用后,如果将变量赋值为null,此时对象会没有引用,但对象的v>0,不会被清除


    下列算法使用 可达性分析算法 判断对象是否被引用:被栈、方法区正在引用着的对象,是可达对象;清理没有引用的对象(清理不可达对象)。

  2. 复制算法:只复制可达的对象到to区(幸存0/1区),其余对象全部清除;
    优点:没有内存碎片
    缺点:因为只复制存活的对象,所以复制算法适用于存活率较低的场景(新生代);如果因为代码问题导致存活率较高时,复制的时间会越来越长。且复制算法的内存占用大

  3. 标记清除算法(Mark-Sweep):顾名思义,将可达对象标记后,清除不可达对象
    优点:内存占用较小
    缺点:清除后内存空间不连续会生成内存碎片

4、标记清除压缩算法(Mark-Sweep-Compact):多次标记清除后,才触发压缩操作。有效减少压缩的执行时间(GMS老年代实际使用的算法


扩展:标记清除其实是三次标记,一次清除,第1、3次标记时会stop the world

标记清除的步骤

所以如果remark标记阶段把A对象标记为1,而程序运行时又将A变为可达对象,但A仍然会被清除


       new对象的时候,对象会出生在伊甸园区,当伊甸园区满了,会执行minorGC(轻量级GC),伊甸园区没有引用的对象和幸存0区(from区)没有引用的对象,大约98%的对象会被minorGC回收,存活的对象copy(复制算法)到幸存1区(to区),然后将存储对象的to区变成from区,将空的from区变成to区,幸存对象的年龄会加1;
       当伊甸园区又满了之后,新的from区(里面是上次minorGC后幸存的对象)中没有引用的对象和伊甸园区没有引用的对象,会被minorGC回收,当幸存对象的年龄达到15,这个对象将会存储到老年代。
       当老年代满了之后会执行majorGC(重量级GC)使用标记清除压缩算法,先标记幸存对象,清除被未标记的对象;多次清理后,整理成内存连续的空间
注:当minorGC执行后,将存活的对象copy到To区时,如果To区内存不够,会直接将剩下的对象放入老年代,所以某些特定场景下可以增大幸存0/1区的内存,减少对象进入老年代的数量,从而减少fullGC


堆内存溢出问题的原因和解决办法:
1、JVM堆内存设置不够
2、老年代满了(存在大量对象,不能被GC清理,对象有引用)
上述问题会引起java.lang.OutOfMemoryError:java heap space 堆内存溢出异常。

解决办法
可以分析MAT(Eclipse Memory Analyzer 内存分析器)
· 分析dump快照文件,快速定位内存泄漏
· 获取堆中对象的数据
· 获取对象相互引用的关系
具体步骤参照另一篇文章:一次线上JVM内存泄漏的分析和解决


JVM的基础调优策略

堆内存分配示意图

堆内存调优常用参数解析:
-Xms :分配初始内存,默认物理内存的1/64
-Xmx:分配最大内存,默认为物理内存的1/4
-XX:MaxTenuringThreshold:对象进入老年区要经过minorGC的次数阈值,默认15,经验值31

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,254评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,875评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,682评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,896评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,015评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,152评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,208评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,962评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,388评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,700评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,867评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,551评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,186评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,901评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,689评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,757评论 2 351

推荐阅读更多精彩内容