有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java什么时候出现内存不足?

最近,在运行应用程序时,我们遇到了内存不足异常

这是异常发生之前的堆转储

Heap
 def new generation   total 1572864K, used 366283K [0x00000006b0000000, 0x000000071aaa0000, 0x000000071aaa0000)
  eden space 1398144K, 13% used [0x00000006b0000000, 0x00000006bbb12d40, 0x0000000705560000)
  from space 174720K, 100% used [0x0000000710000000, 0x000000071aaa0000, 0x000000071aaa0000)
  to   space 174720K,   0% used [0x0000000705560000, 0x0000000705560000, 0x0000000710000000)

 tenured generation   total 3495296K, used 2658714K [0x000000071aaa0000, 0x00000007f0000000, 0x00000007f0000000)
  the space 3495296K,  76% used [0x000000071aaa0000, 0x00000007bcf06ba8, 0x00000007bcf06c00, 0x00000007f0000000)

 compacting perm gen  total 42048K, used 41778K [0x00000007f0000000, 0x00000007f2910000, 0x0000000800000000)
  the space 42048K,    99% used [0x00000007f0000000, 0x00000007f28ccb80, 0x00000007f28ccc00, 0x00000007f2910000)

No shared spaces configured.

看起来老根差不多吃饱了(76%)。我想当它最终达到100%时,OOM就会发生。然而,看起来伊甸园只有13%

有人能解释为什么OOM会发生,即使年轻一代还有一些空间


共 (1) 个答案

  1. # 1 楼答案

    JVM可能抛出OutOfMemoryError的原因有很多,包括

    • Java堆空间:当尝试在任一堆生成中分配大于最大连续可用块的对象或数组时
    • 超出了GC开销限制:当JVM花费在垃圾收集上的时间比例过高时(请参见GCTimeLimitGCHeapFreeLimit
    • PermGen空间(Java 8之前)或元空间(Java 8之后):当类元数据的数量超过MaxPermSizeMaxMetaspaceSize
    • 请求的数组大小超过VM限制:尝试分配长度大于Integer.MAX_VALUE - 2的数组时
    • 无法创建新的本机线程:当达到用户进程的操作系统限制时(请参见^{),或者当没有足够的虚拟内存为线程堆栈保留空间时
    • 直接缓冲区内存:当所有直接字节缓冲区的大小超过MaxDirectMemorySize或当没有可用的虚拟内存来满足直接缓冲区分配时
    • 当JVM无法为其内部结构分配内存时,可能是因为可用虚拟内存不足,或者是因为达到了某些操作系统限制(例如,内存映射区域的最大数量)
    • 当JNI代码无法分配某些本机资源时
    • 等等。更不用说应用程序可以在任何时候抛出OutOfMemoryError本身,仅仅因为开发人员决定这样做

    要找出特定错误的原因,您至少应该查看错误消息、stacktrace和GC日志