Fork me on GitHub

HotSpot VM的堆结构


主要三个空间:young代、old代、permanent代。

young代:当Java应用分配Java对象时,分配到young代。
old代:经历过几次minor GC之后,如果对象还存活,就会被转移到old代。
permanent:存储了VM和Java类的元数据,比如内置的字符串和类的静态变量。

-Xmx和-Xms这个两个命令行选项分别指定yound代加上old代空间的总和的初始最大值和最小值,也就是Java堆的大小。当-Xms的值小于-Xmx的值的时候,Java堆的大小可以在最大值和最小值之前浮动。

当Java应用强调吞吐量和延迟的时候,倾向于把-Xms和-Xmx设置成相同的值,由于调整young代或者old代的大小都需要进行Full GC,Full GC降低吞吐量以及加强延迟。

young代的空间可以通过下面的任意一个命令行选项来设置(两个命令一起配合着用):
-XX:NewSize=<n>[G|M|K]
-XX:MaxNewSize=<n>[G|M|K]

-Xmn<n>{G|M|K} young区空间的最大值。最小值以及最大值。也就是说,young区的大小被固定成这个值了。

有一点需要注意的是,如果-Xms和-Xmx没有被设定成相同的值,而且-Xmn被使用了,当调整Java堆的大小的时候,不会调整young代的空间大小,young代的空间大小会保持恒定。因此,-Xmn应该在-Xms和-Xmx设定成相同的时候才指定。

old代的空间大小可以基于young代的大小进行计算,old代的初始值的大小是-Xms的值减去-XX:NewSize,最大值是-Xmx减去-XX:MaxNewSize,如果-Xmx和-Xms设置成了相同的值,而且使用-Xmn选项或者-XX:NewSize和-XX:MaxNewSize设置成了相同的值,那么old代的大小就是-Xmx减去-Xmn。

permanent代设置
-XX:PermSize=<n>[g|m|k]
-XX:MaxPermSize=<n>[g|m|k]


Full GC
old代触发条件:当old代没有足够空间放置对象的时候,HotSpot VM触发Full GC。
old代触发结果:old代和permanent代的空间都会被垃圾回收,即使permanent代的空间还没有满。
permanent代触发条件:当permanent代没有足够空间放置对象的时候,HotSpot VM触发Full GC。
permanent代触发结果:old代和permanent代的空间都会被垃圾回收,即使old代的空间还没有满。
默认情况下,young代也会被垃圾回收。
除非-XX:+ScavengeBeforeFullGC选项被指定了,-XX:+ScavengeBeforeFullGC关闭FullGC的时候young代的垃圾回收。

posted @ 2019-09-04 16:27  北斗2016  阅读(283)  评论(0编辑  收藏  举报