我试着看看-Xmx和-Xms参数如何影响我的程序并检查我的进程消耗了多少内存.
我写了一个简单的程序,但我无法推断出结果.请帮助.
public static void main( String[] args ) {
char[] array = new char[69926904];
}
Run Code Online (Sandbox Code Playgroud)
我跑了参数-Xms5M -Xmx200M.理想情况下,由于字符占用2个字节,因此在超出内存限制之前应保留100M字符.即使我们说,很少有空间用于指针和长度,我不知道,为什么它在69926904长度后抛出错误 .
谢谢.
apa*_*gin 27
仔细阅读有关分代堆的JVM垃圾收集调整指南,它有望回答您的问题.
使用-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)
Run Code Online (Sandbox Code Playgroud)
你的200M Java堆由2代组成:1/3(66.7M)是YoungGen,2/3(133.3M)是OldGen.
-XX:NewRatio 选项允许更改比例,但默认值2意味着YoungGen将保留堆的1 /(2 + 1)部分.
Java对象不能跨越世代,因此对象的最大大小不能大于最大代.在你的情况下,最大的一代是OldGen:136576K = 139853824,这正是char[69926904](16字节标题+ 2*69926904字节数据)的大小.
Rei*_*ica 11
此信息来自使用5.0 Java [tm]虚拟机调优垃圾收集的 Oracles页面.
首先,了解堆的工作原理非常重要.您可能知道对象(如您的数组)存储在堆中.但是,堆不是一个统一的空间.它实际上分为三代,即青年,终身和永久世代.
当生成填满时,每一代都会发生垃圾收集.物体首先分配给年轻一代,并且由于婴儿死亡,大多数物体死在那里.一些幸存的物体被移动到终身一代.当需要收集终生代时,有一个主要集合通常要慢得多,因为它涉及所有活动对象.
"年轻一代由伊甸园和两个幸存者空间组成.物体最初分配在伊甸园.一个幸存者空间随时都是空的,并作为下一个目的地,复制伊甸园和其他幸存者空间中任何活物的集合.以这种方式在幸存者空间之间复制对象,直到它们足够老到终身,或者复制到终身代."
"与终身代密切相关的第三代是永久代.永久代是特殊的,因为它保存虚拟机所需的数据来描述在Java语言级别没有等价的对象.例如描述类和方法存储在永久世代中."
除了控制总堆大小-Xms的-Xmx参数和参数外,还有控制各个段大小的参数.在您的示例中,您设置的是最大总堆大小,但您仍在使用默认生成比率.
"默认情况下,年轻一代的大小由NewRatio控制.例如,设置-XX:NewRatio = 3意味着年轻和终生的比例为1:3.换句话说,伊甸园和幸存者的总和大小空间将是总堆大小的四分之一."
"在一个理想的小集合中,活体对象被从年轻一代的一部分(伊甸园空间加上第一个幸存者空间)复制到年轻一代的另一部分(第二个幸存者空间).但是,并不能保证所有活动对象将适合第二个幸存者空间.为了确保即使所有对象都是活动的,也可以完成次要收集,必须在终身代中保留足够的可用内存以容纳所有活动对象.在最坏的情况下,这保留内存等于eden的大小加上非空幸存空间中的对象.如果在这种最坏的情况下,终身代中没有足够的可用内存,则会发生主要的集合.
你要做的就是存放一个巨大的物体.这个对象必须适合其中一代,并且根本没有足够大的代.即使堆的总大小大于对象,也无济于事,因为对象不能跨越多代.
尝试在运行代码时添加以下参数:-XX:NewRatio=10.如上所述,这将使终身产生十倍于年轻一代.结果,一个更大的对象将能够适应终身一代.
另一个解决方案是简单地避免使用大量的物体.没有一个大型阵列,而是有几个较小的阵列.
| 归档时间: |
|
| 查看次数: |
1707 次 |
| 最近记录: |