Java 找不到足够的连续内存会导致OOM吗?

Java 找不到足够的连续内存会导致OOM吗?,java,memory-management,out-of-memory,permgen,Java,Memory Management,Out Of Memory,Permgen,我从-Xmx1024m开始编写一些java代码,在某个时候,由于OOM,我得到了一个hprof。hprof仅显示320mb,并提供堆栈跟踪: at java.util.Arrays.copyOfRange([CII)[C (Arrays.java:3209) at java.lang.String.<init>([CII)V (String.java:215) at java.lang.StringBuilder.toString()Ljava/lang/String; (

我从-Xmx1024m开始编写一些java代码,在某个时候,由于OOM,我得到了一个hprof。hprof仅显示320mb,并提供堆栈跟踪:

 at java.util.Arrays.copyOfRange([CII)[C (Arrays.java:3209)
  at java.lang.String.<init>([CII)V (String.java:215)
  at java.lang.StringBuilder.toString()Ljava/lang/String; (StringBuilder.java:430)
  ...
位于java.util.Arrays.copyOfRange([CII)[C(Arrays.java:3209)
位于java.lang.String.([CII)V(String.java:215)
位于java.lang.StringBuilder.toString()Ljava/lang/String;(StringBuilder.java:430)
...
这来自我正在复制的一个大字符串

我记得在某个地方读到(找不到)发生的情况是这些案例是:

  • 进程还没有消耗1gb内存,远远低于
  • 即使heap仍然低于1gb,它也需要一些内存,而对于
    copyOfRange()
    来说,它必须是连续内存,因此即使它还没有超过限制,它也无法在主机上找到足够大的内存,它会因OOM而失败
我曾试图在此(
copyOfRange()
需要一块连续内存)上查找文档,但找不到任何

另一个可能的罪魁祸首是permgen内存不足


有人能证实或反驳连续记忆假说吗?任何指向某个文档的指针都会有所帮助。

如果您使用的是并发标记扫描收集器,您可以获得碎片。但是对于新对象,只要有足够的年轻一代空间,您就不必担心碎片,因为空闲的伊甸园空间始终是连续的不连续的

在许多应用程序中,只有一小部分堆给了年轻一代,因此如果您有一个碎片化的永久空间,并且您创建了一个相对较小的对象(小到最大内存大小的5%),那么您可能会得到OutOfMemoryError


如果运行接近最大内存,则性能会非常差,我建议您减少应用程序使用的内存或增加最大内存。这也会增加生成大小。或者,您可以设置
-XX:NewSize=512m

我正在使用deault GC和1.6,因此它是并发标记扫描。因此,我从你的回答中假设是的,copyOfRange()确实需要连续内存,这可能是我OOM的原因?谢谢你的回答!大型对象——我相信512k及以上——直接进入Sun JDK中的终身一代。这不是perm gen,你会看到perm gen OOM,如果是的话(StringBuffer/Builder toString永远不会单独进入perm gen)。在堆的80%上运行应用程序事件通常会破坏性能。不过,默认的GC甚至可能不是并发标记和扫描。@bestsss根据它是默认的GC,因为1.4我不想说更多关于链接页面质量的内容,我只想说它是非信息性的。这里引用Sun白皮书:I如果希望使用CMS收集器,则必须通过指定命令行选项-XX:+useConMarkSweepGC显式选择它。