2010-10-04 81 views
2

我在Sun JVM(1.6.0_21-b06)上收到PermGen空间错误(确定,它是Oracle :))。选项-XX:MaxPermGen值的增加没有帮助。我知道PermGen是一个用于类元数据等永久对象的空间。项目中的课程数量不是很大〜10 000.在崩溃之前,jvisualvm显示57MB为使用PermGen。导致java.lang.OutOfMemoryError的算法:PermGen空间错误

我想有些算法占用所有可访问的内存。有人知道导致PermGen溢出的算法的例子吗?

UPD。我问这样一个抽象问题,因为在那个时候我不能使用任何分析器 - 代码崩溃如此困难以至于jvisualvm和eclipse停止响应。我需要杀死终端与kill -KILL {process_numer}的java进程。我使用有很多线程和JMS消息传递的糟糕的有组织(但商业)代码。调试是一团糟 - 我首先需要一些想法在哪里看。

+1

你quesion的抽象级别杀死;)。使用Java分析器(例如virtualvm)来找出程序崩溃的原因。如果您发现问题,请重写您的问题。 – Skarab 2010-10-04 13:59:17

+0

只是出于好奇,你能显示你使用的确切的命令行选项吗? – karoberts 2010-10-04 14:04:45

+0

通过了解导致PermGen溢出的代码示例,您会达到什么目的?你是否试图欣赏一个问题,然后从敬仰中产生问题,或者你是否试图修复它?我已经看到这个问题解决方法失败了很多次,最好找到根本原因并解决它。像Skarab建议使用Java分析器。明白如果你是一个研究人员或学生,但看起来不像。 – sjt 2010-10-04 14:25:26

回答

1

Does someone know examples of algorithms that lead to PermGen overflow ?

是的,但是这是什么意思?如果你想解决这个问题,请安装一个类似jprobe或lambda探测器的内存分析器工具,并检查内存泄漏发生的位置,然后解决该问题。现在举个例子:有成千上万的方法来超越烫发空间。我在一个项目中注意到我们继承了使用JMS的应用程序。 jms连接保持打开状态,应用程序在收到很多请求后会在几分钟内崩溃,并且出现类似的错误。值得注意的是:当我们从jboss移动到weblogic(移动到beajrockit)时,它惊人地固定了自己或者至少接受了技术债务的打击。我的建议将与此无关,应该先修复内存泄漏的错误代码,然后修改应用程序服务器和堆空间分配参数。

这是一个有用的链接,包含你所得到的例外信息。 http://www.jroller.com/agileanswers/entry/preventing_java_s_java_lang

编辑

此链接可能是有益的 http://www.precisejava.com/javaperf/j2ee/JMS.htm

+0

我认为在我的情况下,你对JMS的想法是最有前瞻性的。一些消息在崩溃前发送。 – Nulldevice 2010-10-04 15:18:53

+0

关于JMS框架的一点是它是异步的,可以收到几个异步请求,当jms连接没有关闭时它可能导致问题。祝你好运。 – sjt 2010-10-04 15:23:23

4

算法不如实现。下面就来生成随机字符串一个很愚蠢的方式,填补了PermGen的空间:

Random rnd = new Random(); 
    List<String> interned = new ArrayList<String>(); 
    for (;;) { 
     int length = rnd.nextInt(100); 
     StringBuilder builder = new StringBuilder(); 
     String chars = "abcdefghijklmnopqrstuvwxyz"; 
     for (int i = 0; i < length; i++) { 
      builder.append(chars.charAt(rnd.nextInt(chars.length()))); 
     } 
     interned.add(builder.toString().intern()); 
    } 

简而言之:实习弦一两件事是可以吃的PermGen内存。

0

您是否使用不同的垃圾收集器?

The throughput collector will throw an out-of-memory exception if too much time is being spent doing garbage collection. For example, if the JVM is spending more than 98% of the total time doing garbage collection and is recovering less than 2% of the heap, it will throw an out-of-memory expection. The implementation of this feature has changed in 1.5. The policy is the same but there may be slight differences in behavior due to the new implementation.” ” In the J2SE Platform version 1.5 the throughput collector will be chosen as the garbage collector on server class machines.” http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html

查看this的一些说明页面。

3

有两件事情有可能导致PermGen的空间问题:

  1. String.intern(String)方法PermGen的堆创建的字符串。如果您进行了大量实习并直接(或间接)保留对实习字符串的引用,则可以填写PermGen。

  2. 类加载器在PermGen堆中创建JVM内部类描述符和代码段。如果您的应用程序执行了大量的动态类加载,并且类对象不会被垃圾回收,则可以填充PermGen。

热调用Java webapps依赖于动态加载并且是常见的源PermGen问题。根本原因通常是内存泄漏,涉及从某个对象到旧类加载器的隐藏引用。 (Tomcat通常会为此“坚持”,但真正的问题通常在正在重新部署的webapp中)。

AFAIK,@Michael Borgwardt提到的代理案例也是代理实现生成类文件的结果并在飞行中加载它们。