【问题标题】:When does out of memory happen?什么时候内存不足?
【发布时间】:2015-11-25 19:10:27
【问题描述】:

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

这是异常发生前的堆转储

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吗?

【问题讨论】:

  • 因为没有足够的可用内存来分配所请求的空间量。百分比与此无关。 @HNA 如果这是真的,那么 JVM 就不会启动,但你没听说过虚拟内存吗?
  • 我很确定我们的应用程序只会一一分配小变量。所以不会发生需要大块内存的OOM。虚拟内存——是的。我真的很好奇为什么年轻一代仍然是 16% 时会发生 OOM
  • 你确定不是烫发吗? stackoverflow.com/questions/88235/… 已满 99% / 270k 免费编辑:啊不,似乎 permgen 没有报告它的实际最大值:stackoverflow.com/questions/15611423/… 与 1.5G 堆相比,40M 并没有那么多。
  • 您应该粘贴异常本身。

标签: java garbage-collection jvm


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-15
    • 2016-01-04
    • 1970-01-01
    • 2011-07-01
    • 2012-07-06
    • 1970-01-01
    • 2012-07-01
    相关资源
    最近更新 更多