Java 如何在代码中找到内存泄漏的地方?

Java 如何在代码中找到内存泄漏的地方?,java,memory-leaks,out-of-memory,Java,Memory Leaks,Out Of Memory,如何捕获java.lang.OutOfMemoryError:java堆空间? 我有一个服务器,在它运行了几次之后抛出java.lang.OutOfMemoryError:java堆空间。但我无法在代码中找到它发生的位置。在日志中,如果发生,则不进行格式化。 我们分配了8GB内存,错误并没有出现,但服务器在某个时间点开始占用几乎整个内存。 什么工具可以帮助我找到错误 我尝试了VisualJVM,但没用。我找不到内存泄漏的代码 我无法模拟服务器崩溃时的情况 java.lang.OutOfMemor

如何捕获
java.lang.OutOfMemoryError:java堆空间
? 我有一个服务器,在它运行了几次之后抛出
java.lang.OutOfMemoryError:java堆空间
。但我无法在代码中找到它发生的位置。在日志中,如果发生,则不进行格式化。 我们分配了8GB内存,错误并没有出现,但服务器在某个时间点开始占用几乎整个内存。 什么工具可以帮助我找到错误

我尝试了VisualJVM,但没用。我找不到内存泄漏的代码

我无法模拟服务器崩溃时的情况

java.lang.OutOfMemoryError: Java heap space
你一定不能抓住它。程序员不需要对这些进行任何操作。事实上,对错误使用try-catch子句是个坏主意。无法从错误中恢复。错误的唯一解决方案是终止执行。错误与运行应用程序的环境有关。示例包括OutOfMemoryError、StackOverflowerError等

现在,如果您面临这个错误,这意味着是时候重新设计您的应用程序了

  • 检查您的应用程序是否优雅地关闭了所有资源,可能会最终阻塞或类似的情况
  • 检查您正在创建的对象。问问你自己,你是否真的需要一次又一次地创建任何对象,它是否可以是一个单体,该对象的范围是什么——它是否是全局可访问的,该对象的生命是什么
  • 尽量减少对象的范围,我的意思是如果它真的很重要,那么就让对象全局可访问
  • 要分析堆转储,可以使用以下参数执行JVM:

    -XX:+HeapDumpOnOutOfMemoryError writes heap dump on OutOfMemoryError (recommended)
    
    -XX:+HeapDumpOnCtrlBreak writes heap dump together with thread dump on CTRL+BREAK
    
    有一篇关于它的好文章。你可以看到。这可能会解决你的问题。
    您还可以使用-Java Heap Analysis Tool,它位于JDK bin目录中。

    您可以使用诸如JProfiler或VisualVM之类的工具(还有许多其他工具,这里只提到两个选项)来分析堆转储,以确定哪种对象消耗的内存最多。这将使您了解应用程序中不同对象的实例数和内存消耗。有了它,您将能够找出内存泄漏发生的位置


    一些工具(如JProfiler)允许您连接到正在运行的JVM实例,并跟踪方法调用树、创建特定对象的代码位置等,结合从堆转储中提取的上述详细信息,将为您提供更多内存泄漏发生位置的线索。

    请参阅:使用JProfiler。许多IDE还提供自己的分析器。我使用Netbeans。我在生产中有一台大型服务器,大约有数百万用户在3-6小时后发生一些事件,服务器崩溃。我无法模拟服务器崩溃时的情况。如果我不知道模块在哪里崩溃,如何检查数千行代码