Nit*_*raj 5 java jvm out-of-memory jvm-arguments
我正在用Java编写简单的程序来创建2个10亿大小的int数组。我用-Xms10G运行了该程序,即10GB的内存仍然出现OOM错误。以下是代码段。
public class TestBigIntArraySize {
public static int arraySize = 1000_000_000;
public static int [] firstArray = new int[arraySize];
public static int [] secondArray = new int[arraySize];
public static void main(String[] args) {
System.out.println(1000_000_000 * Integer.SIZE);
}
}
Run Code Online (Sandbox Code Playgroud)
就我所能想到的,用于十亿个int数组的内存将是System.out.println(1000_000_000 * Integer.SIZE); 返回1,935,228,928,小于2GB。因此,我的程序总要求最大为4GB。
即使我在方法调用中创建数组并返回数组或静态数组(如下所示)或在main()中,也会收到错误消息。工作所需的内存是12G,是我预期的3倍。我正在使用oracle java:jdk1.8.0_201
我尝试了-Xms10G -XX:NewRatio = 1 ---可行的选项。
但是我想进一步减少内存占用。
我尝试通过给eden提供更多内存的选项,-Xms9G -XX:NewRatio=0.5但是java抱怨非法参数。
我尝试通过选项将数组直接分配给旧gen的选项-Xms9G -XX:NewRatio=1 -XX:PretenureSizeThreshold=10000。但这也给OOM。
这只是一个实验项目,我只是在操纵阵列的位置。我想用最小的内存做到这一点。有人可以建议如何去做吗?什么Java选项,为什么?
因此,假设乘以位长度可能不是获取字节数的最佳方法。正如 @mayamar 所提到的,您的实际内存使用量约为 2*4 giga byte。
无论如何,让我们开始实际的调音乐句。4GB 可能太大了,将直接存储在旧代中。所以你需要增加老一代的大小。更改新的一代设置可能会起作用,但那是......好吧,那么您实际上就关闭了旧的一代。它可能会对测试用例的其他部分造成损害。
您尝试NewRatio=1将新旧世代的比例设置为 1:1,而不是更好的比例,例如 1:100。然而,如果您将比率设置得太大,JVM 可能无法启动(VM 初始化期间进行 GC)。最好只用 指定它MaxNewSize。
最后,运行与此类似的东西将非常接近您的“最小化内存占用”要求。
java -Xmx8400000000 -XX:MaxNewSize=30M -XX:OldSize=8300000000 TestBigIntArraySize
Run Code Online (Sandbox Code Playgroud)
注意:最好留出几十兆字节,因为 JVM 本身需要内存来运行。如果您的程序不像 MVCE 那么小,并且不希望 GC 时不时地启动,则需要留出更多空间。
| 归档时间: |
|
| 查看次数: |
92 次 |
| 最近记录: |