繁体   English   中英

什么时候发生内存不足?

[英]When does out of memory happen?

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

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

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仍会发生吗?

JVM抛出OutOfMemoryError原因有很多,其中包括

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

要找出导致特定错误的原因,至少应查看错误消息,stacktrace和GC日志。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM