java permgen_Java 8:从PermGen到元空间

java permgen

您可能已经知道,现在可以下载JDK 8 Early Access 。 这使Java开发人员可以尝试Java 8的某些新语言和运行时功能。这些功能之一是完全删除自Oracle自JDK 7发行以来就宣布的Permanent Generation(PermGen)空间。例如,自JDK 7起,它已从PermGen空间中删除。JDK8版本完成了其退役工作。 本文将分享我们到目前为止在PermGen后继者Metaspace上找到的信息。 当执行Java程序“泄漏”类元数据对象时,我们还将比较HotSpot 1.7与HotSpot 1.8(b75)的运行时行为。 Java 8正式发布后,有关Metaspace的最终规范,调整标志和文档应可用。

元空间:

新的存储空间诞生了

JDK 8 HotSpot JVM现在正在使用本机内存来表示类元数据,这称为Metaspace。 类似于Oracle JRockitIBM JVM的 。 好消息是,它不再意味着java.lang.OutOfMemoryError:PermGen空间问题,也不再需要您调整和监视此内存空间……不是那么快。 虽然此更改默认情况下是不可见的,但接下来我们将向您显示,您仍然需要担心类元数据的内存占用。 还请记住,此新功能不能神奇地消除类和类加载器的内存泄漏。 您将需要使用其他方法并通过学习新的命名约定来跟踪这些问题。 我建议您阅读PermGen删除摘要和Jon对此主题的评论

综上所述:

PermGen空间状况

  • 此内存空间已完全删除。
  • PermSize和MaxPermSize JVM参数将被忽略,如果在启动时出现警告,则会发出警告。

元空间内存分配模型

  • 现在,类元数据的大多数分配都是从本机内存中分配的。
  • 用来描述类元数据的分类器已被删除。

元空间容量

  • 默认情况下,类元数据分配受可用本机内存量限制(容量将取决于您使用32位JVM还是使用64位以及JVM虚拟操作系统)。
  • 一个新的标志(MaxMetaspaceSize)可用,允许您限制用于类元数据的本机内存量。 如果您未指定此标志,则Metaspace将在运行时根据应用程序需求动态调整大小。

元空间垃圾收集

  • 一旦类元数据使用量达到“ MaxMetaspaceSize”,就会触发死类和类加载器的垃圾收集。
  • 为了限制此类垃圾收集的频率或延迟,显然将需要对Metaspace进行适当的监视和调整。 过多的Metaspace垃圾回收可能是类的征兆,类加载器的内存泄漏或应用程序的大小不足。

Java堆空间影响

  • 一些其他数据已移至Java堆空间。 这意味着在将来的JDK 8升级之后,您可能会发现Java堆空间的增加。

元空间监控

  • HotSpot 1.8详细GC日志输出中提供了元空间用法。
  • 根据我们对b75的测试,此时Jstat和JVisualVM尚未更新,并且仍然存在旧的PermGen空间引用。

现在有足够的理论,让我们通过泄漏的Java程序来了解这个新的内存空间在起作用……

PermGen与Metaspace运行时比较

为了更好地理解新的Metaspace内存空间的运行时行为,我们创建了一个泄漏Java程序的类元数据。 您可以在此处下载源代码。

将测试以下方案:

  • 使用JDK 1.7运行Java程序,以监视和耗尽设置为128 MB的PermGen内存空间。
  • 使用JDK 1.8(b75)运行Java程序,以监视新的Metaspace内存空间的动态增加和垃圾回收。
  • 使用JDK 1.8(b75)运行Java程序,以通过将MaxMetaspaceSize值设置为128 MB来模拟元空间的耗尽。

JDK 1.7 @ 64位– PermGen耗尽

  • 具有50K配置的迭代的Java程序
  • Java堆空间为1024 MB
  • Java PermGen空间为128 MB(-XX:MaxPermSize = 128m)

如您所见,从JVisualVM中可以看到,PermGen耗尽是在加载大约30K +类之后达到的。 我们还可以从程序和GC输出中看到这种消耗。

Class metadata leak simulator

Author: Pierre-Hugues Charbonneau

http://javaeesupportpatterns.blogspot.com

ERROR: java.lang.OutOfMemoryError: PermGen space

现在,让我们使用HotSpot JDK 1.8 JRE执行该程序。

JDK 1.8 @ 64位– Metaspace动态调整大小

  • 具有50K配置的迭代的Java程序
  • Java堆空间为1024 MB
  • Java Metaspace空间:无界(默认)

从详细的GC输出中可以看到,JVM Metaspace确实从20 MB扩展到328 MB的保留本机内存,以适应Java程序中增加的类元数据内存占用量。 我们还可以观察到JVM试图破坏任何无效类或类加载器对象的垃圾回收事件。 由于我们的Java程序正在泄漏,因此JVM除了动态扩展Metaspace内存空间外别无选择。 该程序能够在没有OOM事件的情况下运行其50K迭代,并加载了50K +类。 让我们转到最后一个测试场景。

JDK 1.8 @ 64位–元空间耗尽

  • 具有50K配置的迭代的Java程序
  • Java堆空间为1024 MB
  • Java元空间空间:128 MB(-XX:MaxMetaspaceSize = 128m)

从JVisualVM可以看到,在加载大约30K +类之后,达到了元空间消耗。 与JDK 1.7的运行非常相似。 我们还可以从程序和GC输出中看到这一点。 另一个有趣的发现是保留的本机内存占用空间是指定的最大大小的两倍。 如果可能的话,这可能表明有些机会可以微调元空间调整大小策略,以避免本机内存浪费。

现在在下面找到我们从Java程序输出中获得的Exception。

Class metadata leak simulator

Author: Pierre-Hugues Charbonneau

http://javaeesupportpatterns.blogspot.com

ERROR: java.lang.OutOfMemoryError: Metadata space

做完了!

不出所料,像我们使用JDK 1.7进行基线运行一样,将Metaspace的上限限制为128 MB,这使我们无法完成程序的50K迭代。 JVM引发了一个新的OOM错误。 内存分配失败后,JVM从元空间引发了上述OOM事件。

#metaspace.cpp

最后的话

希望您对此早期分析和使用新的Java 8 Metaspace进行试验表示赞赏。 当前的观察结果明确表明,将需要进行适当的监视和调整,才能避免出现诸如上一次测试场景中触发的过多Metaspace GC或OOM条件之类的问题。 未来的文章可能会包括性能比较,以识别与此新功能相关的潜在性能改进。

参考: Java 8: Java EE支持模式和Java教程博客中的JCG合作伙伴 Pierre-Hugues Charbonneau 从PermGen到Metaspace

翻译自: https://www.javacodegeeks.com/2013/02/java-8-from-permgen-to-metaspace.html

java permgen

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值