Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
导致java.lang.OutOfMemoryError的算法:PermGen空间错误_Java_Heap - Fatal编程技术网

导致java.lang.OutOfMemoryError的算法:PermGen空间错误

导致java.lang.OutOfMemoryError的算法:PermGen空间错误,java,heap,Java,Heap,我在Sun JVM(1.6.0_21-b06)上遇到PermGen空间错误(好的,是Oracle:)。增加选项-XX:MaxPermGen值没有帮助。我知道PermGen是一个用于类元数据等永久对象的空间。项目中的班级数量并没有这么大~10000。崩溃前,jvisualvm显示57MB为已用PermGen 我猜某些算法占用了所有可访问的内存。有人知道导致PermGen溢出的算法示例吗 UPD.我问了这样一个抽象的问题,因为现在我无法使用任何探查器-代码崩溃得如此厉害,以至于jvisualvm和e

我在Sun JVM(1.6.0_21-b06)上遇到PermGen空间错误(好的,是Oracle:)。增加选项-XX:MaxPermGen值没有帮助。我知道PermGen是一个用于类元数据等永久对象的空间。项目中的班级数量并没有这么大~10000。崩溃前,jvisualvm显示57MB为已用PermGen

我猜某些算法占用了所有可访问的内存。有人知道导致PermGen溢出的算法示例吗


UPD.我问了这样一个抽象的问题,因为现在我无法使用任何探查器-代码崩溃得如此厉害,以至于jvisualvm和eclipse停止响应。我需要使用kill-kill{process_numer}从终端杀死java进程。我使用的是有很多线程和JMS消息传递的糟糕的组织(但商业)代码。调试是一团糟-我需要一些想法,首先看看哪里。

与其说是算法,不如说是实现。下面是一种生成填充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());
    }
Random rnd=new Random();
List interned=新建ArrayList();
对于(;;){
int length=rnd.nextInt(100);
StringBuilder=新的StringBuilder();
字符串chars=“abcdefghijklmnopqrstuvxyz”;
for(int i=0;i

简而言之:插入字符串是一件会消耗PermGen内存的事情。

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

如果花费太多时间进行垃圾收集,吞吐量收集器将抛出内存不足异常。例如,如果JVM花费超过98%的总时间进行垃圾收集,并且恢复的堆不到2%,那么它将抛出内存不足的预期。此功能的实现在1.5中已更改。该策略是相同的,但由于新的实现,在行为上可能略有不同。”“在J2SE平台1.5版中,吞吐量收集器将被选为服务器级机器上的垃圾收集器。”

查看第页上的一些说明。

如果您大量使用,也可能会占用您的永久空间

有人知道导致PermGen溢出的算法示例吗

是的,但这有什么意义呢?如果要修复此问题,请安装一个内存探查器工具,如jprobe或lambda probe,并检查内存泄漏发生的位置,然后进行修复。 现在举个例子:有数千种方法可以超越perm gen空间。我在一个项目中注意到,当我们继承了一个应用程序时,他们正在使用JMS。jms连接保持打开状态,应用程序在收到大量带有类似错误的请求后几分钟内崩溃。需要注意的是:当我们从jboss迁移到weblogic(迁移到beajrockit)时,它惊人地修复了自己,或者至少承受了技术债务的打击。我的建议是,不管怎样,应该先修复内存泄漏的坏代码,然后修补应用服务器和堆空间分配参数

下面是一个有用的链接,其中包含有关您正在获得的异常的一些信息。

编辑

此链接可能会有所帮助
检查内存分析器-。它是一个java转储内存分析器。发生意外错误后,它非常有用。

有两种情况可能会导致永久性空间问题:

  • String.intern(String)
    方法在PermGen堆中创建字符串。如果您进行了大量的内部操作,并直接(或间接)保留对内部字符串的引用,则可以填充PermGen

  • 类装入器在PermGen堆中创建JVM内部类描述符和代码段。如果您的应用程序执行大量动态类加载,并且类对象没有被垃圾收集,那么您可以填充PermGen

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


    好吧,@Michael Borgwardt提到的代理案例也是代理实现生成类文件并动态加载它们的结果。

    您的问题的抽象级别杀死了;)。使用Java探查器(例如virtualvm)找出是什么使程序崩溃。如果您发现问题,请重写您的问题。出于好奇,您是否可以显示您正在使用的确切命令行选项?通过了解导致PermGen溢出的代码示例,您将获得什么?你们是在赞美一个问题,然后在赞美中制造问题,还是在试图解决它?我见过这种解决问题的方法失败很多次,最好寻找根本原因并加以解决。就像Skarab建议的那样,使用Java探查器。如果您是一名研究人员或学生,则可以理解,但似乎不是这样。@Nulldevice我看到您注意到了jms消息。我有一个与JMS相关的类似问题,请检查您的JMS连接是否已关闭。检查我下面的答案,它有更多的细节。要提供更具建设性的反馈,请尝试。它是一个java转储内存分析器。在发生意外错误后,它非常有用。我认为在我的例子中,您关于JMS的想法是最有前景的。一些消息是在崩溃之前发送的。JMS框架的特点是它是异步的,可以接收多个异步请求,当JMS连接未关闭时,可能会导致问题。祝你好运。