JAVA JVM 堆内存 GC 及 内存分配

JAVA 中 分堆内存 和 堆外内存

堆外内存不是由JVM控制的,这个得开发人员自己手工调用方法去释放

堆内内存是由JVM控制,可以由JVM 通过算法自动 GC

JAVA 在 JVM 启动的时候,就事先对堆内存进行了划分了几个模块

默认情况下 JVM 堆内存分配:

<table>
<tr>
<th colspan="4">新生代 (占堆内存 1/3)</th>
<th rowspan="3">老年代 (占堆内存 2/3)</th>
</tr >
<tr >
<td>Eden</td>
<td>Survivor0</td>
<td>Survivor1</td>
</td></td>
</tr>
<tr>
<td>80%</td>
<td>10%</td>
<td>10%</td>
</td></td>
</tr>
</table>

JVM 将堆内存划分了2个大模块

新生代: 当我们使用了一个新对象,申请内存的时候,就是先从新生代内存里申请

老年代: 当新生代的内存经过了15次 GC 还没被 GC 掉 或者 当新申请的内存比较大的时候,直接从老年代里分配

新生代 GC

新生代里又分划分了 Eden , Survivor0, Survivor1 三个区域

翻译过来的 就是 伊甸园 , 存活0区 , 存活1区

伊甸园是《圣经》故事中人类的始祖亚当和夏娃居住的乐园。所以作者也很意思。

实际 Eden , Survivor0, Survivor1 三个区域职责如下:

Eden : 当申请内存的时候,从 Eden 里申请(当申请的内存大于JVM启动参数 PretenureSizeThreshold 的值的时候,直接从 老年代里分配内存,默认值为0,所有都从Eden分配), 当 Eden 里不够内存的时候,会进行一次普通GC

Survivor : 当 Eden 内存不够的时候,普通GC, 将 Eden 里没被引用等的内存GC掉,把活下来的,转到 Survivor 区域

这里为什么不写是 Survivor0 或者 Survivor1

因为 Survivor0 和 Survivor1 两个区域干的活是一样, Survivor0 和 Survivor1 相交替干活的

可以理解为,每次GC,只有 其中一个可用。

例如,当前 Survivor0 和 Survivor1 都会空

第一次新生代GC

Eden 里GC存活来的内存,转移到 Survivor0, 并且给那些活下来的对象 “寿命”+1

第二次新生代GC

将Eden 和 Survivor0两个区域活下来的内存转移到 Survivor1

然后再将 Eden 和 Survivor0两个都区域的全清空

并且给那些活下来的对象 “寿命”+1

第三次新生代GC

将Eden 和 Survivor1两个区域活下来的内存转移到 Survivor0

然后再将 Eden 和 Survivor1 两个都区域的全清空

并且给那些活下来的对象 “寿命”+1

第 N 次新生代GC

将 “寿命” >= 15 的对象,转移到 老年代。

假如 Eden 和 Survivor 区域活下来的对象需要的空间 大于 Survivor0 的空间。则找出哪一个 寿命及以上的 总合大于 Survivor0 的空间,则将那个年龄及对上的 对象转移到 老年代(其实就是按年龄倒序排序,直接那个 Survivor 中其中一个 区域够存为止)

每次新生代GC 都是只用 Survivor 其中一个区域,把另一个空出来,待下一次的时候,这就是大家常说的 复制GC

但这样可以理解为至少有一个 Survivor 区域内存是没有真正存数据的

老年代 GC

新生代 GC 后 Survivor0或者Survivor1 不够存 新生代 GC 之后活下来的对象 的时候

会新生代 将 “寿命” >= 15 的对象 或者 Survivor0 不够存按年龄大小倒序排出来的对象 转移到 老年代

但是老年代的空间,也是有限的,默认情况下占当前 JVM 堆空间的 2/3

老年代普通GC

当老年代里的 <font color="#F00">连续内存空间</font> 大于 新生代转移过来的内存块的时候,则会进行一次 老年代普通 GC

Full GC

当老年代里的 <font color="#F00">连续内存空间</font> 小于 新生代转移过来的内存块的时候,则会进行 Full GC

Full GC 是对整个堆空间进行GC

如果Full GC后还是无法给新创建的对象分配内存,或者无法移动那些需要进入老年代中的对象,那么JVM抛出 Out Of Memory Error

小结

  1. JVM 是中整个堆当内存不够的时候,会进行 Full GC , 当Full GC 内存还是不够的时候,会抛出 Out Of Memory Error

  2. JVM 新生代,老年代内存分配比例是可以通过启动参数控制的

  3. Map ,Set , ArrayList 等对象中存存储的数据,需要开发人员手动 remove 掉,要不然GC 可能不会释放(除非WeakHaspMap等对象),很容易让堆占满,导致Full GC

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

推荐阅读更多精彩内容