我正在尝试运行一个简单的JUnit测试,其中包括以下代码:
@Test
public void testVeryLongString() {
String s = "0123456789";
String repeated = new String(new char[214748364]).replace(" ", s);
assertEquals(2147483640, repeated .length());
}
它在上面几行失败,并显示"请求的数组大小超过VM限制"。
我尝试将此测试的运行配置增加到-Xmx18292m(在64GB的Windows工作站上(,但我仍然收到可怕的"请求的阵列大小超过VM限制"。
我错过了什么?
有没有一种方法可以让测试继续进行而不会在这个VM限制上失败?
请求的数组大小超过VM限制
意味着试图分配大于Integer.MAX_VALUE
的数组由于Java 9String
和StringBuilder
(用于String.replace(...)
(在内部使用两倍于字符串长度的字节数组,而不是相同长度的char
数组。
有了Java 8和足够的内存(比-Xmx18292m
多得多,因为执行String.replace(...)
需要额外的数组(来避免OutOfMemoryError
,应该可以工作。
为了获得更好的性能和更少的内存需求,请使用以下代码:
@Test
public void testVeryLongString() {
String s = "0123456789";
char[] chars = new char[214_748_364 * s.length()]; // Java 9+: 107_374_182
for (int i = 0; i < chars.length; i += s.length()) {
for (int j = 0; j < s.length(); j++) {
chars[i+j] = s.charAt(j);
}
}
String repeated = new String(chars);
assertEquals(2_147_483_640, repeated.length()); // Java 9+: 1_073_741_820
}