如何解读GC输出?关于Occupancy与Size的区别及占比计算疑问
GC日志中Occupancy与Size的核心疑问解答
1. Occupancy(占用量)和Size(容量)的本质区别
- Size(容量):是JVM给内存区域(比如新生代、老年代)分配的总内存上限,对应日志里括号中的
567890K。它由启动参数(如-Xmx、-Xmn)直接控制,相当于内存区域的“最大容纳量”。 - Occupancy(占用量):是该区域里当前被存活对象实际用掉的内存大小,也就是日志里的
12345K(GC前)和12000K(GC后)。打个比方,Size是杯子的总容积,Occupancy就是杯子里实际装的水的体积。
2. Occupancy的计量逻辑
Occupancy统计的是存活对象占用的总字节数,不是对象的数量。JVM会逐一扫描内存区域里的存活对象,把每个对象实际占用的内存加起来——这里的内存包括对象头、实例数据,还有为了内存对齐填充的字节(JVM通常按8或16字节对齐,哪怕对象实际数据没填满,也会补上空白字节)。比如一个对象实际数据占12字节,加上对象头和对齐后可能占16字节,这16字节会被算进Occupancy。
3. GC配置中占用占比的计算规则
不管是G1的-XX:InitiatingHeapOccupancyPercent,还是其他GC类型里的占用触发阈值,这个占比都是**(当前Occupancy大小)/(对应内存区域的Size大小)**,完全按内存容量的比例计算,和对象数量没有关系。比如设置-XX:InitiatingHeapOccupancyPercent=50,意思是当整个堆的实际占用量达到堆总容量的50%时,触发并发标记流程。
内容的提问来源于stack exchange,提问作者Victor Grazi
相关产品推荐
相关产品推荐

