下面是程序,
public class Dummy {
public static void main(String[] args) throws Exception {
final int LENGTH = Integer.MAX_VALUE / 8;
Object[] values = new Object[LENGTH];
int count = 0;
for (int i = 0; i < Integer.MAX_VALUE; i++) {
Object o = new Object();
int hashCode = o.hashCode();
if (hashCode > LENGTH)
continue;
if (values[hashCode] != null) {
System.out.println("found after " + count + ": " + values[hashCode] + " same hashcode as " + o);
System.out.println(values[hashCode] == o);
System.exit(0);
} else {
System.out.println(hashCode);
values[hashCode] = o;
count++;
}
}
}
}
当通过 eclipse(通过 64 位 javaw.exe
)启动时,堆使用率一直上升到低于显示的近似值(最大值)并且电池在几分钟内耗尽,
然后显示以下异常:
Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
在同一台机器上,使用 64 位启动时相同的程序 java.exe
在命令行中,在 for-loop
中创建 22985 个对象后,新的哈希码始终与以前的哈希码发生冲突“私有(private)工作集”值为 1GB(最大)。
:
23206321
39915397
found after 22985: java.lang.Object@f2eb847 same hashcode as java.lang.Object@f2eb847
false
我想了解一下,而无需过多关注代码逻辑,
1) 为什么比较这两种方法在堆使用方面存在差异?因为这两种方法都没有进行调整。
2)
在通过 eclipse(javaw.exe
)或通过命令行(java.exe
)启动程序之前,我如何控制堆使用参数?请帮助我!!!
注意:我正在使用 java 1.6
最佳答案
如果您不指定 JVM 使用 Ergonomics (决定设置默认值)基于主机架构,它为 JVM 设置各种默认参数,heap 就是其中之一
对于 64 位 CPU,JVM 设置了更高的堆值,因此您会看到 OOM 延迟
你可以通过调用
来验证这一点java -XX:+PrintFlagsFinal -version 2>&1 | grep MaxHeapSize
由于您使用的是 Windows,因此您可以使用一些 JDK 工具,也可以使用此程序来验证内存默认调整
long maxBytes = Runtime.getRuntime().maxMemory();
System.out.println("Max memory: " + maxBytes / 1024 / 1024 + "M");
在两台机器上
您还可以通过显式指定堆大小来覆盖堆大小,在这种情况下您应该从内存的角度看到类似的行为
关于java - 使用 "javaw.exe"与 "java.exe"的堆大小使用情况,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27664355/