永久生成:默认值的容量是固定的还是会根据需要增长?
我们注意到运行 Solaris 10 的客户的永久 GC 容量从 50% 增长到 97%。该 JVM 使用默认值“permgen”(我们没有将任何自定义 Permgen FLAG 传递给 JVM)。
我们是否应该设置更高的 PermGen 值,而不是在生产环境中以 97% 的 PermGen 空间运行?
PS:我们在 Solaris 10 上使用 JDK 1.6.0_23。
更新 我们是否应该认为它很快就会出现 OutOfMemoryError 错误?或者 JVM 是否有可能增加容量,使使用率降至 97% 以下?
we are noticing that our customer running Solaris 10 is having Permanent GC grow from 50% to 97% of capacity. This JVM was using the default value of "permgen" (we did NOT pass any custom Permgen FLAG to the JVM).
Instead of running at 97% permgen space in production, should we set a higher value of PermGen ?
P.S : we're using JDK 1.6.0_23 on solaris 10.
UPDATE
Should we think that anytime soon, it could do a OutOfMemoryError ? OR is it possible that the JVM will increase capacity so that the usage falls below 97% ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
PermGen 将增长到预定的最大值(您可以从命令行设置),然后停止。 PermGen 区域主要保存类定义,通常在加载大量类并且不释放它们的应用程序中,您会用完 PermGen - 要么因为它们太大,要么在 Web 应用程序中,因为某些东西意外保留在其类加载器被释放后到一个类。您需要确定 PermGen 是否持续增长,或者最终是否稳定。
PermGen will grow up to a predetermined maximum (which you can set from the command line) and then stop. The PermGen area holds primarily class definitions, and usually you run out of PermGen in applications that load a lot of classes and don't release them -- either because they're just big or, in web apps, because something is accidentally holding on to a class after its classloader has been released. You need to determine whether PermGen keeps growing and growing, or whether it eventually stabilizes.
使用的 PermGen 空间可能会随着时间的推移而增长,导致应用程序代码中出现某些内存泄漏/错误,或者在您正在使用的库中。
例如,在使用 Spring 和 log4j 的 Apache Tomcat 中运行 Web 应用程序时,如果 Web 应用程序实例重新加载次数过多,我们经常会遇到问题,显然 log4j 存在一些问题,即它无法从类加载器中正确卸载某些类。
所以,是的,泄漏可能会导致 PermGen 空间随着时间的推移而增长,就像正常的内存泄漏一样。
PermGen space used may grow over time to certain memory leaks / bugs in the application code, or in the libraries you are using.
For example we frequently see problems when running a webapp in Apache Tomcat which uses Spring and log4j if the webapp instance is reloaded too many times, apparently log4j has some issues where it does not properly unload certain classes from the classloader.
So yes, it is possible to have leaks that cause PermGen space to grow over time, just like normal memory leaks.
你的推理有点不清楚。
如果您预计会失败,为什么不采取防御方法并立即增加
-XX:MaxPermSize
呢?Your reasoning is a little unclear.
If you anticipate a failure, why not take the defensive approach and increase the
-XX:MaxPermSize
right away?在注意到永久代激增之前,您的客户应用程序中是否存在重大代码更改?或者一直都是这样(从 50% 到 97%)?
我想此时这并不重要,但在某些情况下,在系统测试期间应该可以检测到这样的峰值(假设您的团队在客户的系统测试周期中具有可见性。)
可以肯定的是,以 97 运行为了舒适起见,% 太接近最大值了,您将不得不使用最大 perm gen 参数(并且因此使用其他堆参数......很可能。)
这不是一个好主意。您应该(必须)始终在部署之前表征您(或您的客户)的应用程序。您的客户应该告诉您他们需要哪些参数,或者您的团队必须在 UAT 和系统测试周期中确定这些参数(假设您对这些参数有可见性;请参见上文。)
这不是不可避免的,但有可能(特别是如果应用程序尚未承受最大可能的负载)。如果峰值是最近出现的现象,则也有可能。在这种情况下,很可能是由于代码更改或由于其他因素(操作系统、容器中的补丁、客户流量的变化、数据库的变化等)导致的先前未知的情况。
海事组织,是的。如果您(或您的客户)可以描述或估计应用程序的内存(永久内存和堆内存)要求(以及当前和未来可能的流量),您应该给自己留出 10%-20% 的余量,以防万一。少了就等于是在玩火。任何更多的事情很可能都是浪费。
内存可能很便宜,但应用程序性能和稳定性却不便宜;)
如果您还没有使用过 VisualGc,那么您应该使用它。它是一个很好的工具,可以直观地检查 JVM 内存中不同段的情况。还有 VisualVM,它更强大、更通用,而 VisualGc UI 的读数演示特别适合此任务。
我认为这并不重要。您的应用程序容器是什么(如果您的应用程序正在其中运行)。您可能需要编辑您的帖子以包含此容器。
Was there a significant code change in your customer's application prior to noticing the spike in perm gen? Or has it always been like this (going from 50% to 97%)?
I guess it doesn't really matter at this point, but in some cases, spikes like this should be detectable during system testing (assuming your team has visibility in your customers' system testing cycle.)
One thing for certain is that running at 97% is way too much close to the max for comfort, and you will have to play with the max perm gen parameters (and as a consequence with other heap parameters... most likely.)
Not a good idea. You should (read must) always characterize your (or your customers) applications before deployment. Either your customers should tell you what params they need, or your team must determine those during UAT and system test cycles (assuming you have visibility on those; see above.)
It is not an inevitability, but it is a possibility (especially if the app has not been subjected to the max possible load yet.) It is also possible if the spike is a recent phenomenon. In that case, due, most likely, to a code change, or a previously unknown condition due to other factors (a patch in the OS, in the container, change in customer traffic, change in the db, etc.)
IMO, yes. If you (or your customer) can characterize or estimate the app's memory (both perm and heap) requirements (as well as current and possible future traffic), you should give yourself a 10%-20% margin, just in case. Anything less is just playing with fire. Anything more most likely will be wasteful.
Memory might be cheap, but application performance and stability are not ;)
If you haven't use visualgc, you should. It's a good tool to visually inspect what's going with the different segments in your JVM memory. There is also visualvm, which is more powerful and versatile, yet, the visualgc UI presentation of readings is specifically suitable for this task.
I don't think that should matter. What is your application container (if your app is running in one.) You might want to edit your post to include this.
我相信 JVM 将使用与普通堆相同的策略来扩展永久生成堆。
现在,如果 GC 后 Permgen 堆已满 97%,那么 Permgen 很可能已经扩展到配置的最大大小(您的情况下的默认值)。
不可能说 OOME 即将到来。 (这取决于您的应用程序的行为方式,以及导致其增加永久生成使用量的原因。)但是,谨慎应该:
I believe that the JVM will use the same strategy for expanding the permgen heap as it does with the normal heap.
Now if the permgen heap is 97% full after GC, then it is highly likely that permgen has already been expanded to the maximum size configured (the default in your case).
It is impossible to say where an OOME is imminent. (It depends on how your application behaves, and what is causing it to increase permgen usage.) However, it would be prudent to:
PermGen 大小有一个最大限制,当达到此大小时,您会收到 OutOfMemoryError 错误。然而,如果您的空间已满 97%,并不意味着您已达到最大容量,而只是当时分配的空间的 97%。 (另外3%,如果可以的话,就必须增加空间)
There is a maximum PermGen size and you get an OutOfMemoryError when this si reached. However if you are 97% full it doesn't mean you are at your maximum, just 97% of the space allocated at that time. (In another 3% it will have to grow the space if it can)