G1垃圾收集器,永久带和元数据区

G1垃圾收集器,永久带和元数据区

我们收到了一些围绕G1垃圾收集器和使用永久带的一些问题。当G1作为垃圾收集器的时候,hotspot JVM并没有使用永久带,这看上起可能有点迷惑。下面是一些澄清:

JDK7:永久带

JDK7和它的更新中仍然存在永久带,所有的垃圾收集器都在使用。在JDK7里面,开始进行去掉永久带的努力,永久带中的一些数据已经被转移到java堆或者是native堆中了。但是,永久带并没有完全被移除,在JDK7和更新版本中仍然存在。下面列出了JDK7中从永久带移除的东西:

符号引用被移到了native堆
池化string对象被移到了java堆
Class对象、静态变量被移到了java堆

JDK7:G1和永久带

在G1垃圾收集器中,只有在进行full GC的时候,永久带才会被回收,这一过程是stop-the-world的。当不做Full GC的时候,G1运行是最优化的。只有当永久带满了或者应用分配内存的速度超过了G1回收垃圾的速度的时候,G1才会触发Full GC。

在CMS垃圾收集器中,我们可以使用-XX:+CMSClassUnloadingEnabled在CMS concurrent cycle中回收集永久带。在G1里面没有对应的设置。G1只有在stop-the-world的Full GC的时候,才会回收永久带。

我们可以根据应用的需要,设置PermSize和MaxPermSize参数来调优永久带的大小。

JDK8:永久带

JDK8中已经完全移除了永久带。这项工作是在这个bug:https://bugs.openjdk.java.net/browse/JDK-6964458推动下完成的。JDK8中,PermSize和MaxPermSize参数也一并移除了。

移除永久带项目的邮件:http://mail.openjdk.java.net/pipermail/hotspot-dev/2012-September/006679.html

JDK8:元数据区

在JDK8中,类的元数据存放在native堆中,这个空间被叫做:元数据区。JDK8中给元数据区添加了一些新的参数。

  • -XX:MetaspaceSize=<NNN> <NNN>是分配给类元数据区(以字节计)的初始大小(初始高水位),超过会导致垃圾收集器卸载类。这个数量是一个估计值。当第一次到达高水位的时候,下一个高水位是由垃圾收集器来管理的。
  • -XX:MaxMetaspaceSize=<NNN> <NNN>是分配给类元数据区的最大值(以字节计)。这个参数可以用来限制分配给类元数据区的大小。这个值也是个估计值。默认无上限。
  • -XX:MinMetaspaceFreeRatio=<NNN>,<NNN>是一次GC以后,为了避免增加元数据区(高水位)的大小,空闲的类元数据区的容量的最小比例,不够就会导致垃圾回收。
  • -XX:MaxMetaspaceFreeRatio=<NNN>,<NNN>是一次GC以后,为了避免减少元数据区(高水位)的大小,空闲的类元数据区的容量的最大比例,超过就会导致垃圾回收。

默认情况下,类元数据的分配仅受限于可用的本地内存。我们可以使用新的MaxMetaspaceSize参数限定类元数据可用的本地内存的数量。它类似于MaxPermSize。当类元数据区使用量到达MetaspaceSize(32位机客户端模式12M,32位服务器模式16M,64位机会更大)的时候,会触发垃圾回收,然后回收掉无用的类加载器和class对象。MetaspaceSize的值设置的过大会延长垃圾回收时间。垃圾回收过后,引起下一次垃圾回收的类元数据空间的大小可能会变大。

猜你喜欢

转载自blog.csdn.net/u013276888/article/details/80553097