写点什么

Java 8 会解决 PermGen OutOfMemoryError 问题吗?

2013 年 3 月 11 日

Java 8会解决PermGen OutOfMemoryError**** 问题吗

Oracle 正在合并 HotSpot 和 JRockit 的代码库,作为该项目的一部分,Oracle 宣布他们会将PermGen 从Java 8 的HotSpot JVM 中移除。然而很多人都认为这意味着所有的PermGen 错误也将消失不见。因为现在可以通过 Java 8 Early Access 构建版本来检查移除 PermGen 的效果,所以是时候看看是不是所有 PermGen 问题都已解决了。

PermGen**** 是什么?

Jon Masamitsu(JVM 开发者,现就职于 Oracle)曾于 2006 年在其博客上解释过永久代(Permanent Generation)的用途:永久代包含了类相关的信息,包括字节码、名字和JIT 等信息。它被保存在一个独立的空间中,因为它通常是静态的,垃圾收集改为垃圾回收。

PermGen**** 带来的问题

很多开发者都在其系统中见过“java.lang.OutOfMemoryError: PermGen space”这一问题。这往往是由类加载器相关的内存泄漏以及新类加载器的创建导致的,通常出现于代码热部署时。相对于正式产品,该问题在开发机上出现的频率更高,正是这个原因。当它在产品中出现时,开发者可以拿到生成的堆转储文件,并利用像 Eclipse Memory Analyzer Toolkit 这样的工具来寻找应该卸载却没被卸载的类加载器。除非通过特定配置阻止,PermGen 也是会进行垃圾回收的。然而,在出现内存泄漏时,就没什么可回收的了。在产品中最常见的“问题”是 64MB 这个默认值太低了。常用的解决方法是将其设置为 256MB。

Java 8**** 改变了什么

Jon 在 HotSpot 开发邮件列表中解释了 Java 8 将发生的变化:Java 8 中再也没有 PermGen 了。其中的某些部分,如被 intern 的字符串,在 Java 7 中已经移到了普通堆里。其余结构在 Java 8 中会被移到称作“Metaspace”的本机内存区中,该区域在默认情况下会自动生长,也会被垃圾回收。它有两个标记:MetaspaceSize 和 MaxMetaspaceSize。

应 InfoQ 的要求,Jon Masamitsu 解释了其背后的设计目标:

移除了 PermGen,用户就无需考虑如何正确设置其大小了,这是我们的一个目标。

如果知道应用程序的类数据需要更多空间,可以把 MetaspaceSize 设置的比默认值大些。 这能减少一些启动时的 GC 次数。不过没必要这么做。除非你想尽量减少 GC 次数,否则我不建议这么做。

如果想限制类数据所占空间的大小,可以设置 MaxMetaspaceSize。如果怀疑出现类加载器泄漏,并且希望应用在耗尽太多本机内存前停止,应该设置它。还有一种使用场合,那就是在一个服务器上运行了多个应用,而且用户希望限制每个应用所占的类空间大小。

因此设置 MetaspaceSize 会潜在影响头几次垃圾回收,大部分情况下并不重要。这也反映出类似旧式 PermSize 标记的用途。

在设置了 MaxMetaspaceSize 的情况下,该空间的内存仍然会耗尽,进而引发“java.lang.OutOfMemoryError: Metadata space”错误。因为类加载器的泄漏仍然存在,而通常 Java 又不希望无限制地消耗本机内存,因此设置一个类似于 MaxPermSize 的限制看起来也是合理的。与 PermGen 类似,verbose: GC 日志会打印 Metaspace 当前的内存消耗情况。使用命令行标记 PermSize 或 MaxPermSize 会导致一个警告,通知用户切换为 Metaspace 标记。

结论

因为 Metaspace 和 PermGen 的理念几乎是相同的,管理员在将 Java 7 升级到 Java 8 时,只需执行 sed 'e/Perm/Metaspace/g’就能修改相应标记。

总的来说,变化看起来平淡无奇。大多数情况下,只是名字变了一下。默认情况下不限制 Metaspace,以避免所选的默认值太小,但为了保证系统的稳定性又需要设置一下最大值。幸运的是我们可以复用 PermSize 和 MaxPermSize 的配置——几乎每个人都用过——只需要改一下标记即可。遗憾的是,从托管 Java 堆迁移到本机内存意味着堆转储文件中有价值的故障诊断信息少了许多,这正是 Kirk Pepperdine所担忧的

最后,类加载器泄漏的问题和以前一样,仍然会出现。

译者补记

英文站原新闻下有些评论,读者 Ronald Miura 并不同意本文的结论,他不客气地评论道:

如果将类信息加载到有限内存区域中,最后会出现 OutOfMemoryError。如果不使用有限的区域,你会得到“不稳定的系统”。

还“平淡无奇”,你想要什么,让 JVM 自动修正你的内存泄漏 bug 吗?

来自 Oracle 的 Cameron Purdy 倒是很平和:

还是会好一些的。之前不管是不是需要,JVM 都会吃掉那块空间……如果设置得太小,JVM 会死掉;如果设置得太大,这块内存就被 JVM 浪费了。理论上说,现在你完全可以不关注这个,因为 JVM 会在运行时自动调校为“合适的大小”。

peter lin 对 Ronald Miura 的意见表示赞同,他补充说:

过去我使用并测试过 JRockit,由 JVM 来管理 PermGen,开发者就轻松多了。我都记不清 tomcat 用户在邮件列表中问过我多少次相关的问题了。

Ronald Miura 后来又补充了一下自己的意见:

……我认为这种改变是巨大的进步。

我很反感本文的结论,把这种改动诋毁为“平淡无奇”。如果你期望的是无解问题(自动修复你的 bug)的神奇方案,那才算“平淡无奇”吧。

亲爱的 InfoQ 读者,你怎样看待这个问题?欢迎参与讨论。

查看英文原文 Will Java 8 solve PermGen OutOfMemoryError?

2013 年 3 月 11 日 03:53789
用户头像
臧秀涛 略懂技术的运营同学。

发布了 300 篇内容, 共 117.2 次阅读, 收获喜欢 26 次。

关注

评论

发布
暂无评论
发现更多内容

BIGO技术 | Paxos的工程实践与极致优化

InfoQ_3597a20b53cc

技术

硬核干货:葡萄城 SpreadJS 前端表格技术分享

Geek_Willie

Excel SpreadJS 表格控件 表格开发

池化技术到达有多牛?看了线程和线程池的对比吓我一跳!

王磊

Java

真香!Linux 原来是这么管理内存的

cxuan

Linux 操作系统

顺势昌,逆势亡:人啊,得学会做信天翁,而不是鹧鸪鸟

非著名程序员

创业 程序员 管理 提升认知

What's New in Dubbo-go v1.5

apache/dubbo-go

golang dubbo

计算机网络基础(十)---网络层-迪杰斯特拉算法

书旅

算法 计算机网络 网络 最短路径

到底一台服务器能够支持多少TCP并发连接?

南方有乔木兮

一个小实验,来

池建强

算法 薪资

当远程工作成为未来的工作方式......

Atlassian

Atlassian Jira

如何成为一个成功的首席数据官

尹千觞

4. JSON字符串是如何被解析的?JsonParser了解一下

YourBatman

Jackson JSON库

将Arch Linux安装到U盘

Kurtis Moxley

Linux 安装操作系统

腾讯“神盾-联邦计算”平台带你翻越数据合作的重重大山

小小的一朵云

大数据

如何设计一个亿级消息量的IM系统

Chank

Java Architecture Architect IM Instant Messaging

央行数字货币或将成为经济“内循环”的未来加速器

CECBC区块链专委会

数字经济 全球经济下行 降息 惠普金融深化

BIGO技术 | Paxos的工程实践与极致优化

InfoQ_3597a20b53cc

BIGO

《深度工作》学习笔记(2)

石云升

学习 专注 深度工作

原创 | 使用JPA全面实现DDD持久化【关于本书】

编程道与术

Java hibernate DDD JDBC jpa

大厂经验(4):iOS端埋点自动采集技术原理剖析

DeeperMan

ios 前端 数据采集 埋点

week08 总结

Z冰红茶

LeetCode题解:142. 环形链表 II,JavaScript,快慢指针,详细注释

Lee Chen

LeetCode 前端进阶训练营

蚂蚁上市:P7可获1200万元期权,酸酸酸酸酸...

程序员生活志

互联网热点 蚂蚁金服

秒杀全网!研发、运营必备实用工具网站

程序员生活志

工具类网站

CDN百科第八期 | 我的网站到底需不需要CDN加速?

阿里云Edge Plus

网站 CDN 云直播

第八周作业

田振宇

QQ音乐PB级ClickHouse实时数据平台架构演进之路

小小的一朵云

大数据

案例解读:深入理解浏览器的缓存机制

华为云开发者社区

缓存 浏览器 服务器 缓存穿透 华为云

实战:docker搭建FastDFS文件系统并集成SpringBoot

生命在于折腾

springboot

企业为何需要建立统一的复用型软件平台?

力软.net/java开发平台

Java 企业信息化 开发工具 框架 平台应用服务

乘商用之风,破后疫情之浪:丁耘分享华为如何持续护航5G新价值

脑极体

Java 8会解决PermGen OutOfMemoryError问题吗?-InfoQ