堆的核心概述
内存细分 现代垃圾收集器大部分都给予分代收集理论设计,堆空间细分为:
约定:新生区=新生带=年轻代 养老区=老年区=老年代 永久区=永久代
设置推内存大小和OOM
OutOfMemoryError
异常年轻代与老年代
(YoungGen)
和老年代(OldGen
)Eden空间
、Survivor0空间
和Survivor1空间
(有时也叫做from区
、to区
)配置新生代和老年代在堆结构中的占比
Survivor
空间缺省所占的比例是8:1:1-XX:SurvivorRation=8
对象分配过程
为对象分配内存是一件非常严谨和复杂的任务,JVM的设计者们不仅需要考虑内存如何分配、在哪里分配等问题,并且由于内存分配算法和内存回收算法密切相关,所以还需要考虑GC执行完,内存回收后是否会在内存空间中产生内存碎片
Eden区
,此区有大小限制Eden
的空间填满时,程序又需要创建对象,JVM垃圾回收器将对Eden区进行垃圾回收(Minor GC),将Eden区中的不再被其他对象引用的对象进行销毁,再加载新的对象到Eden区中Eden空间
的剩余对象放入Survivor0空间
Survivor0空间
的,如果没有回收将会放到Survivor1空间
Survivor0空间
,接着再去Survivor1空间
-XX:MaxTenuringThreshold=<N>
进行设置GC:Major Gc
,进行老年代的内存清理Major Gc
之后发现任然无法进行对象的保存,就会产生OOM异常java.lang.OutOfMemoryError:Java heap space
Minor GC、Major GC、Full GC
JVM在进行GC时,并非每次都对上面三个内存区域一起回收的,大部分时候回收的都是指新生代 针对HotSpot Vm的实现,他里面的GC按照回收区域又分为两大种类型:一种是部分收集
(Partial GC
),一种是整堆收集(Full GC)
(Minor GC/Young GC)
:只是新生代的垃圾回收(Major GC/Old GC)
:只是老年代的垃圾收集 CMS GC
会有单独收集老年代的行为Major GC
和Full GC
混淆使用,需要具体分辨是老年代回收还是整堆回收(Mixed GC)
:收集整个新生代以及部分老年代的垃圾收集。 G1 Gc
会有这种行为(Full GC)
:收集整个Java堆和方法区的垃圾收集
(Minor GC)
触发机制
Minor GC
,这里的年轻代满指的是Eden区满,Survivor区
满不会引发GC。(每次Minor GC
会清理年轻代的内存)Minor GC
非常频繁,一般回收速度也比较快。这一定义即清晰又易于理解Minor GC
会引发STW,暂停其他用户的线程,等垃圾回收结束,用户线程才恢复运行(Major GC)
触发机制
Major GC
或Full GC
发生了Major GC
,经常会伴随至少一次的Major GC
(但非绝对的,在Partial Scavenge
收集器的收集策略里就有直接进行Major GC
的策略选择过程) Minor GC
,如果之后空间还不足,则会触发Major GC
Major GC
的速度一般会比Minor GC
慢10倍以上,STW的时间更长Major GC
后,内存不足,就报OOM
System.gc()
时,系统建议执行Full GC,但是不必然执行Minor GC
后进入老年代的平均大小大于老年代的可用内存Survivor Space0(Form Space)区
和Survivor Space1(To Space)区
复制时,对象大小大于To Space
可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小 Full GC
是开发或调优中尽量要避免的,这样暂时时间会短一些内存分配策略(或对象提升(Promotion)规则)
如果对象在
Eden区
出生并经过第一次Minor GC
后任然存活,并且能被Survivor区
容纳的话,将被移动到Survivor区
中,并将对象年龄设为1。对象在Survivor区
中每熬过一次Minor GC
,年龄就增加1岁,当它的年龄增加到一定程度时(默认15岁,其实每个JVM、每个GC都有所不同),就会被晋升到老年代中 对象晋升老年代的年龄阈值,可以通过选项-XX:MaxTenuringThreshold
来设置
针对不同年龄段的对象分配原则如下:
Survivor区
中相同年龄的所有对象大小的总和大于Survivor区
空间的一半,年龄大于或等于该年龄的对象可以直接进入老年代,无须等到MaxTenuringThreshold
中要求的年龄-XX:HandlePromotionFailure
对象分配过程:TLAB(Thread Local Allocation Buffer)
什么是TLAB?
为什么会有TLAB?
TLAB说明
堆空间常用参数
参数 | 作用 |
---|---|
-XX:+PrintFlagsInitial | 查看所有的参数的默认初始值 |
-XX:+PrintFlagsFinal | 查看所有的参数的最终值(可能会存在修改,不再是初始值) |
-Xms:初始堆空间内存(默认为物理内存的1/64) | 初始堆空间内存 |
-Xmx:最大堆空间内存(默认为物理内存的1/4) | 最大堆空间内存 |
-Xmn:设置新生代的大小 (初始值及最大值) | 设置新生代的大小 |
-XX:NewRation | 配置新生代与老年代在堆结构的占比 |
-XX:SurvivorRation | 设置新生代中Eden区和S0/S1区的比例 |
-XX:MaxTenuringThreshold | 设置新生代垃圾的最大年龄 |
-XX:PrintGCDetails | 输出详细的GC处理日志 |
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有