代码之家  ›  专栏  ›  技术社区  ›  pjj

“java.lang.outofmemoryError:gc overhead limit exceeded”是否表示内存泄漏?

  •  0
  • pjj  · 技术社区  · 6 年前

    我正在了解有关内存泄漏的更多信息,并尝试以下代码:

    我有下面的代码 Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "main"

    import com.learn.general.memoryleaks.LeakFactory.Leak;
    
    public class InnerClassMemoryLeakTest {
        static Leak[] leaks = new Leak[100000];
    
        public static void main(String[] args) {
            while(true) {
                for (int i = 0; i < leaks.length; i++) {
                    leaks[i] = new LeakFactory().getLeak();
                }
            }
        }
    
        private static void createLeak() {
            while(true) {
                for (int i = 0; i < leaks.length; i++) {
                    leaks[i] = new LeakFactory().getLeak();
                }
            }
        }
    }
    
    
    import java.util.Calendar;
    
    public class LeakFactory {
    
        double d = Math.random();
        Calendar calendar = Calendar.getInstance();
    
        public Leak getLeak(){
            return new Leak();
        }
    
        public class Leak{
            double d_i = Math.random();
            Calendar calendar_i = Calendar.getInstance();
        }
    }
    

    然后我有下面的代码 Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded

    import java.util.ArrayList;
    import java.util.Calendar;
    import java.util.List;
    
    public class ArrayListMemoryLeak {
    
        public static void main(String[] args) {
            List<Object> calendars = new ArrayList<>();
            int count = 0;
            while(true){
                calendars.add(Calendar.getInstance());
            }
        }
    }
    

    问题: 第一种情况下的错误是否表示存在内存泄漏,而第二种情况下则不是?

    3 回复  |  直到 6 年前
        1
  •  0
  •   hagrawal7777    6 年前

    根据您的评论:

    我想知道关于记忆泄漏的事,所以我想做的是 …我在找两个案例的解释,以及是否首先 case表示内存泄漏,第二个case不显示

    简而言之,这两个错误都表明JVM内存不足,现在,无论是由于内存泄漏还是没有内存不足,JVM都是不同的问题。

    现在,进入第一个案例——是的,有一个内存泄漏(尽管是故意的),因为内部类包含封闭类的引用,所以使用 new LeakFactory() 有资格参加GC,但因为 Leak 内部类对它们有很强的引用。

    为了看得更清楚,改变你的 public class Leak{ public static class Leak{ 您会注意到,与最初的非静态相比,JVM将运行更长一点,OOM将在几秒钟后出现。 漏泄 内部类。

        2
  •  1
  •   Makoto    6 年前

    内存泄漏是程序员的结果。 无意中 保存内存的时间比它们应该的要长,这样无意中的内存使用会慢慢积累,直到没有剩余的可分配内存为止。

    在爪哇,内存泄漏是 艰难的 给定垃圾收集的性质以及它实际上如何查看对象引用的强度(或弱)程度。

    鉴于你必须 故意 你自己把这些课程都搞得一团糟,没什么好争论的;你 故意 这样做。您已经创建了足够多的引用,以至于耗尽了自己的内存限制。

    Java中的内存泄漏通常以一种偷偷摸摸的方式表现出来;一些引用被保存在A中。 finalize() 方法,直到类被实际垃圾收集后才会释放,并且只有VM知道实际发生的时间(可能永远不会发生)。谢天谢地 that method is going away Soon™ 因此,使用 那个 至少有一点点减少。

    你也可以 难以置信地 恶与行 Unsafe things with the language 但是,这已经足够危险了,大多数明智的IDE和工具集会在您手上出现重大内存泄漏之前警告您这种用法。

    所有这些都要说……不。你看到的例外情况表明你的内存不足。它不是 直接地 表示内存泄漏。

        3
  •  -1
  •   Zachary Thomas    6 年前

    太多的对象的引用丢失,因此被垃圾收集。默认情况下,如果超过98%左右的程序处理都是专门用于处理被丢弃的对象(内存被回收),那么JVM会讨厌这种情况。您可以重新调整对象的用途(通过使其可变并将其重新分配为新用途直接自行回收),也可以通过向命令行添加-xx:-usegcoverheadlimit来禁用构成错误的通知。当我自己做大量的遗传算法时,有几次我遇到了这个问题,其中许多孩子是由父母创造的,然后在下一个繁殖循环之前,你杀死了大多数最不适合的孩子。基本上,你创造了比Java更喜欢的垃圾,即使你可能还没有做错什么。只需将-xx:-usegcoverheadlimit添加到命令行参数中,然后查看是否再次发生这种情况。要了解在使用Eclipse时添加它的位置,请遵循以下说明 http://www.planetofbits.com/eclipse/increase-jvm-heap-size-in-eclipse/ 但把这条线改为-xx:-用gcoverheadlimit