在我的单元测试中,我故意尝试引发一个OutOfMemoryError异常。我使用了类似以下的简单语句:
byte[] block = new byte[128 * 1024 * 1024 * 1024];
这段代码在Win7 64位系统上,使用jdk6u21 64位版本能够正常运行。但是当我在Centos 5 64位系统上,使用相同的jdk6u21版本运行时,即使我将数组大小扩大,也没有抛出OutOfMemoryError异常。
有什么想法吗?
在我的单元测试中,我故意尝试引发一个OutOfMemoryError异常。我使用了类似以下的简单语句:
byte[] block = new byte[128 * 1024 * 1024 * 1024];
这段代码在Win7 64位系统上,使用jdk6u21 64位版本能够正常运行。但是当我在Centos 5 64位系统上,使用相同的jdk6u21版本运行时,即使我将数组大小扩大,也没有抛出OutOfMemoryError异常。
有什么想法吗?
Linux不总是立即分配您请求的所有内存,因为许多实际应用程序要求比它们需要的更多。这称为超额承诺(它也意味着有时会猜错,然后可怕的OOM killer会袭击)。
对于您的单元测试,我只会手动抛出OutOfMemoryError。
如果您只想使用所有内存,请按照以下步骤操作:
try {
List<Object> tempList = new ArrayList<Object>();
while (true) {
tempList.add(new byte[128 * 1024 * 1024 * 1024]);
}
} catch (OutOfMemoryError OME) {
// OK, Garbage Collector will have run now...
}
128*1024*1024*1024=0 因为 int 类型是 32 位,Java 不支持超过 4GB 的数组。
你可以使用-Xmx
标志,故意将JVM的最大堆大小设置为一个较小的值。
运行以下程序:
public final class Test {
public static void main(final String[] args) {
final byte[] block = new byte[Integer.MAX_VALUE];
}
}
使用以下JVM参数:-Xmx8m
这样就可以了:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at Test.main(Test.java:4)
ulimit -v 102400
ulimit -d 102400
unitTest.sh
以上代码应该将您的单元测试限制在1M虚拟内存和1M数据段大小。当您达到其中任何一个时,您的进程应该得到ENOMEM错误。请注意,这些限制适用于调用它们退出的进程/ shell;您可能希望在子shell中运行它们。
有关其工作原理的详细信息,请参阅man 2 setrlimit
。使用help ulimit
命令了解ulimit命令。
虽然是小问题,但分配新的long[Integer.MAX_VALUE]会使内存使用速度快8倍。(每个约16 GB)
throw new OutOfMemoryError();
的答案,但现在没有意义了... +1 - David Z