Java进程内存检查测试

Java进程内存检查测试,java,memory,Java,Memory,我试图查看-Xmx和-Xms参数对程序的影响,并检查进程消耗了多少内存 我写了一个简单的程序,但无法推理出结果。请帮忙 public static void main( String[] args ) { char[] array = new char[69926904]; } 我使用参数-Xms5M-Xmx200M运行。理想情况下,由于一个字符需要2个字节,因此在超过内存限制之前,它应该能容纳100个字符。即使我们说,很少有空间用于指针和长度,我也不知道为什么它在699269

我试图查看
-Xmx
-Xms
参数对程序的影响,并检查进程消耗了多少内存

我写了一个简单的程序,但无法推理出结果。请帮忙

public static void main( String[] args ) {
        char[] array = new char[69926904];
}
我使用参数
-Xms5M-Xmx200M
运行。理想情况下,由于一个字符需要2个字节,因此在超过内存限制之前,它应该能容纳100个字符。即使我们说,很少有空间用于指针和长度,我也不知道为什么它在69926904length之后抛出错误

谢谢。

仔细阅读关于世代堆的内容,希望它能回答您的问题

使用
-XX:+PrintGCDetails
选项运行Java,一切都应该变得清晰:

Heap
 PSYoungGen      total 3584K, used 294K [0x00000000fbd60000, 0x00000000fc160000, 0x0000000100000000)
  eden space 3072K, 9% used [0x00000000fbd60000,0x00000000fbda9860,0x00000000fc060000)
  from space 512K, 0% used [0x00000000fc0e0000,0x00000000fc0e0000,0x00000000fc160000)
  to   space 512K, 0% used [0x00000000fc060000,0x00000000fc060000,0x00000000fc0e0000)
 PSOldGen        total 136576K, used 136576K [0x00000000f3800000, 0x00000000fbd60000, 0x00000000fbd60000)
  object space 136576K, 100% used [0x00000000f3800000,0x00000000fbd60000,0x00000000fbd60000)
 PSPermGen       total 21248K, used 2595K [0x00000000ee600000, 0x00000000efac0000, 0x00000000f3800000)
  object space 21248K, 12% used [0x00000000ee600000,0x00000000ee888db0,0x00000000efac0000)
您的200米Java堆由两代组成:1/3(66.70万)是YoungGen,2/3(133.3万)是OldGen

-XX:NewRatio
选项允许更改比例,但默认值2表示YoungGen将保留堆的1/(2+1)部分


Java对象不能跨代,因此对象的最大大小不能大于最大代。在您的例子中,最大的一代是OldGen:136576K=139853824,它正好是字符[69926904](16字节头+2*69926904字节数据)的大小。

此信息来自上的Oracles页

世世代代 首先,了解堆是如何工作的很重要。您可能知道,对象(如数组)存储在堆中。但是,堆不是一个统一的空间。它实际上分为三代,即年轻一代、终身一代和永久一代

垃圾收集在每一代中发生,当该代填满时。对象首先在年轻一代分配,由于婴儿死亡率,大多数对象在那里死亡。一些幸存的对象将被移动到终身世代。当需要收集终身生成时,有一个主要的收集通常要慢得多,因为它涉及所有活动对象

“年轻一代由伊甸园和两个幸存者空间组成。 对象最初在伊甸园中分配。一个幸存者空间为空 随时,并作为下一次复制的目的地 收集伊甸园和其他幸存者空间中的所有活体。 以这种方式在幸存者空间之间复制对象,直到它们被复制为止 年龄大到可以终身监禁,或复制到终身监禁的一代。”

“与终身制一代密切相关的第三代是 永久的一代。永久的一代之所以特别是因为 保存虚拟机所需的数据,以描述执行以下操作的对象 在Java语言级别上没有等价性 描述类和方法的对象存储在永久数据库中 一代人。”

一些参数 除了控制总堆大小的
-Xms
-Xmx
参数外,还有一些参数控制各个段的大小。在您的示例中,您设置了最大总堆大小,但仍然使用默认的生成比率

默认情况下,年轻一代的大小由NewRatio控制 例如,设置-XX:NewRatio=3意味着 而终身一代的比例是1:3,也就是说 伊甸园和幸存者空间将占总堆的四分之一 尺寸。”

问题 “在理想的次要集合中,活动对象是从一个集合中复制的 年轻一代的一部分(伊甸园空间加上第一个幸存者) 空间)到年轻一代的另一部分(第二个幸存者 但是,不能保证所有活动对象都将 放入第二个幸存者空间。确保未成年人 即使所有对象都处于活动状态,也可以完成收集 必须在终身世代中保留内存,以容纳所有 活动对象。在最坏的情况下,此保留内存等于 伊甸园的大小加上非空幸存者空间中的物体。何时 终身一代中没有足够的内存用于此 最坏的情况是,将发生一个主要的集合

您要做的是存储一个巨大的对象。这个对象必须适合一代,而且根本没有足够大的代。即使堆的总大小大于对象,这也没有帮助,因为对象不能跨越多代

尝试的事情 在运行代码时,请尝试添加以下参数:
-XX:NewRatio=10
。如上所述,这将使终身世代比年轻世代大十倍。因此,终身世代中可以容纳更大的对象


另一个解决方案是避免使用如此庞大的对象。与其使用一个庞大的数组,不如使用几个较小的数组。

您熟悉永久性生成吗:?@heikkim谢谢您的回复。我浏览了链接。但这里说
Permsize
配置不在Xmx配置范围内。因此,这应该不是问题t对同一个字符没有任何影响?有趣的是,您的结果与每个字符的3字节表示形式一致:
(200M*1024*1024)/69926904=2.999…
“对象的最大大小不能大于最大生成”。超级整洁:D