【问题标题】:Java OutOfMemory ErrorJava OutOfMemory 错误
【发布时间】:2014-04-02 19:20:40
【问题描述】:

我看到 OutOfMemory 问题,我不确定是PERM GEN 区域还是堆空间。错误消息没有说明哪个区域内存不足。

这是部分堆栈跟踪: 以下是可能对 BETWEENNESS 的开发人员有用的信息: java.util.zip.ZipFile.open(Native Method) 的 java.lang.OutOfMemoryError 和 java.util.zip.ZipFile.(ZipFile.java:127) 的java.util.zip.ZipFile.(ZipFile.java:143) 在 com..util.internal.ZipFiles.unzip(ZipFiles.java:91) 我使用 jmap -heap 命令查看了内存不足之前的堆空间:

 using thread-local object allocation.
 Parallel GC with 23 thread(s)

 Heap Configuration:
    MinHeapFreeRatio = 40
    MaxHeapFreeRatio = 70
    MaxHeapSize      = 31675383808 (30208.0MB)
    NewSize          = 1310720 (1.25MB)
    MaxNewSize       = 17592186044415 MB
    OldSize          = 5439488 (5.1875MB)
    NewRatio         = 2
    SurvivorRatio    = 8
    PermSize         = 21757952 (20.75MB)
    MaxPermSize      = 536870912 (512.0MB)

 Heap Usage:
 PS Young Generation
 Eden Space:
    capacity = 9762177024 (9309.9375MB)
    used     = 7286558512 (6949.003707885742MB)
    free     = 2475618512 (2360.933792114258MB)
    74.64071276403028% used
 From Space:
    capacity = 396230656 (377.875MB)
    used     = 340623360 (324.84375MB)
    free     = 55607296 (53.03125MB)
    85.96592788620576% used
 To Space:
    capacity = 398131200 (379.6875MB)
    used     = 0 (0.0MB)
    free     = 398131200 (379.6875MB)
    0.0% used
 PS Old Generation
    capacity = 1992163328 (1899.875MB)
    used     = 1455304512 (1387.8865356445312MB)
    free     = 536858816 (511.98846435546875MB)
    73.05146578825087% used
 PS Perm Generation
    capacity = 418578432 (399.1875MB)
    used     = 418567008 (399.1766052246094MB)
    free     = 11424 (0.010894775390625MB)
    99.99727076238844% used }

此外,我还向 JVM 提供了以下参数:-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/ 但我没有看到任何堆。

我的问题是为什么没有生成堆以及如何确定 JVm 的哪一部分已满。

谢谢。

【问题讨论】:

  • 这里是 jmap -heap 命令的输出:
  • 您使用的是 glassfish 之类的服务器吗?
  • 不,我不是,它是我正在运行的 java 应用程序
  • 看起来 PermGen 的使用率为 99.99%,所以尝试增加它。同时转储堆并使用Eclipse Memory Analyzer 找出内存泄漏的位置。您的应用程序内存也在爆炸。
  • 99.99% 是当前分配的 400MB 的已用内存。 500MB 是 PERM GEN 的总容量,占使用总容量的 80%。

标签: java jvm out-of-memory


【解决方案1】:

您提供的信息表明,您的 PermGen 已满 99%。你的堆已经 73% 满了。所以两者都增加一点也不坏。

您还可以使用-XX:+PrintGCDetails 激活垃圾收集器的日志记录,以获取有关您的JVM 如何使用内存的详细信息。另外激活-XX:+PrintGCTimeStamps-XX:+PrintGCDateStamps-Xloggc:$filename 将日志发送到一个文件,您可以使用 IMB PMAT toolGCViewer 之类的内容轻松分析该文件。

此外,您应该考虑使用VisualVM 在运行时监控您的应用程序。

此外: 我的一位同事发现了一种聪明的方法,可以通过 gdb 更快地获得堆转储:

cat > /tmp/dodump <<EOF
gcore jvm.core
detach
quit
EOF
time gdb --batch --command=/tmp/dodump --pid=`pgrep java`
jmap -dump:format=b,file=jvm.hprof `which java` jvm.core
rm jvm.core
gzip -9 jvm.hprof 

Source

功劳完全归他所有。

【讨论】:

  • 我已经尝试使用 jmap 来分析正在运行的堆。但是注意跳出不寻常的地方。而且,99% 是分配的使用的PERM GEN 内存。但是分配的内存(399MB)还没有达到满容量(500MB)
【解决方案2】:

根据堆栈跟踪,OutOfMemoryError 发生在 ZipFile.open() 本机方法中。这意味着问题与 Java 堆大小无关,也与 PermGen 无关。它可能与 JDK 库内部 malloc'ed 或 mmap'ed 的 ZIP 缓存有关。

尝试添加-Dsun.zip.disableMemoryMapping=true JVM 选项,看看是否有帮助。
打开的 ZIP 文件有多大?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-12
    • 2018-09-29
    • 1970-01-01
    • 2016-02-28
    • 2016-11-14
    • 1970-01-01
    相关资源
    最近更新 更多