当前位置: 首页 > 知识库问答 >
问题:

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

颜安宁
2023-03-14

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

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

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就会发生。然而,看起来eden只有13%。

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

共有1个答案

谢烨烨
2023-03-14

JVM可能抛出OutOfMemoryError有十几个不同的原因,包括

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

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

 类似资料:
  • 问题内容: 我了解到,标准输出()中的所有内容都会显示在Java控制台窗口中(启用后)。我在某个地方发现了某些情况,例如在某些情况下,Swing应用程序对此没有尝试。是这样吗 基本上,什么情况或设置我都不会期望在控制台中看到标准输出? 例如,在JDK上运行而不是在JRE上运行的行为是否有所不同?javaw.exe? ps,我了解如何在Java设置中显示控制台,但我很好奇,因为我设法创建了一个应用程

  • 问题内容: 在我的应用程序中,有时会引发以下异常: 很难找到错误,因为在stacktrace中没有列出我的方法。那么,有人知道何时抛出此异常吗?感谢您的任何提示。 问题答案: 您可以在stacktrace中看到错误: 适配器的内容已更改,但ListView没有收到通知。确保不从后台线程修改适配器的内容,而仅从UI线程修改。 您应该调查一个线程,并使其与UI线程同步。 在Android中执行此操作的

  • 本文向大家介绍为什么会出现浮动?在什么时候需要清除浮动呢?相关面试题,主要包含被问及为什么会出现浮动?在什么时候需要清除浮动呢?时的应答技巧和注意事项,需要的朋友参考一下 @xiangshuo1992 是的,有相关联,第75天的题是问了它的工作原理,今天是问它为什么会出现浮动,还是有些区别。呵呵,我出题时,就猜到你会记得之前有出过了……果然

  • 我已经用Java编写代码一段时间了。但有时,我不知道什么时候应该抛出异常,什么时候应该捕获异常。我正在做一个有很多方法的项目。层次结构是这样的- 所以目前我正在做的是-我在所有方法中抛出异常并在方法A中捕获它,然后将其记录为错误。 但我不确定这是否是正确的方法?或者我应该开始在所有方法中捕获异常。这就是为什么这种混乱始于我的 - 我什么时候应该抓住异常与何时应该抛出异常。我知道这是一个愚蠢的问题,

  • 问题内容: 我对JAX-WS进行了概述,并注意到了(和)的一些引用。 在什么情况下需要?(我认为JSR 109服务器?!) 问题答案: 是使用SUN的参考实现将Web服务作为标准存档部署在非Java EE5 Servlet容器上时所需的专有部署描述符。 Sun的RI 用作servlet上下文事件的侦听器和调度程序servlet。两者都必须在中声明。然后需要该文件为定义Web服务端点,以使其知道必须

  • 问题内容: 我怎么能说: 为什么函数调用中不需要括号,而最后一行呢? 问题答案: 是一个功能 调用该函数并产生该函数返回的任何值。 setTimeout的目的是在一段时间后运行代码。你需要的功能只是传递给它(这样的setTimeout可以自称在适当的时候函数),因为如果你将它传递给setTimeout的前调用的函数(用括号),将执行 现在 而不是1秒后,。