内存何时发生?

时间:2015-11-25 19:10:27

标签: java garbage-collection jvm

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

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

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 个答案:

答案 0 :(得分:6)

JVM可能抛出def options(playerVsComputer, playerVsPlayer): playerN = input("How players are you?") if input == 1: playerVsComputer() if input == 2: playerVsPlayer() options() 的原因有很多,包括

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

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