[英]Setting Java Max heap size doesn't throw any error in infinite loop program
我有以下代码。
import java.util.Scanner;
import java.lang.Thread;
class Hello{
public static void main(String[] args){
try{
long count =0;
for(;;){
A a = new A();
count++;
if(count%100 ==0)
System.out.println("Created "+ count);
}
}
catch(Exception ex){
System.out.println("Exception occured");
System.out.println(ex);
}}
}
class A{
int a = 10;
String str = generateRandom();
String str1 = generateRandom();
String str2 = generateRandom();
String str3 = generateRandom();
String str4 = generateRandom();
String str5 = generateRandom();
String str6 = generateRandom();
String str7 = generateRandom();
String str8 = generateRandom();
String str9 = generateRandom();
String str10 = generateRandom();
String rst1 = generateRandom();
String rst2 = generateRandom();
String rst3 = generateRandom();
String rst4 = generateRandom();
String rst5 = generateRandom();
String rst6 = generateRandom();
String rst7 = generateRandom();
String rst8 = generateRandom();
String rst9 = generateRandom();
String rst10 = generateRandom();
private static String generateRandom() {
String aToZ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
Random rand=new Random();
StringBuilder res=new StringBuilder();
for (int i = 0; i < 17; i++) {
int randIndex=rand.nextInt(aToZ.length());
res.append(aToZ.charAt(randIndex));
}
return res.toString();
}
我正在使用以下命令运行Java应用程序。
java -Xmx100M您好
我希望它会在一段时间后引发Memory异常,但该程序运行时消耗了几乎100%的CPU,而没有崩溃,并且几乎一直只占用80.66MB。
我知道-Xmx仅设置堆大小,而不设置其他与程序相关的大小。
如果我们设置-Xmx,应用程序是否将通过频繁运行GC以降级模式运行,从而仅占用有限的堆大小?
您不会保留一个以上的A
对象,因此所需的内存量不会增加。
for(;;) {
A a = new A();
} // doesn't need `a` any more.
一个简单的解决方案是保留每个对象。
public class Main {
public static void main(String... args) {
int count = 0;
try {
List<Object> as = new ArrayList<>();
for (; ; ) {
as.add(new Object());
count++;
if (count % 1000000 == 0)
System.out.println(count);
}
} catch (OutOfMemoryError e) {
System.out.println("Created " + count + " objects");
}
}
}
我建议使用-Xmx1g -Xms1g -verbose:gc
运行它
注意:由于该程序将在死亡之前尝试通过清理来保持运行,因此可能要花很长时间才能放弃。 也就是说,GC的时间随着内存的大小而增加,并且随着您开始运行不足而增加。
是。 如果设置-Xmx,则应用程序将通过仅占用有限的堆大小而以降级模式运行,并且由于您不缓存对象,因此GC会连续执行垃圾回收。 只需尝试以下代码即可获得预期的异常。
import java.util.Scanner;
import java.lang.Thread;
import java.util.Random;
import java.util.ArrayList;
class Hello{
public static void main(String[] args){
try{
long count =0;
ArrayList<A> x = new ArrayList<A>();
for(;;){
A a = new A();
x.add(a);
count++;
if(count%100 ==0)
System.out.println("Created "+ count);
}
}
catch(Exception ex){
System.out.println("Exception occured");
System.out.println(ex);
}
}
}
class A{
int a = 10;
String str = generateRandom();
String str1 = generateRandom();
String str2 = generateRandom();
String str3 = generateRandom();
String str4 = generateRandom();
String str5 = generateRandom();
String str6 = generateRandom();
String str7 = generateRandom();
String str8 = generateRandom();
String str9 = generateRandom();
String str10 = generateRandom();
String rst1 = generateRandom();
String rst2 = generateRandom();
String rst3 = generateRandom();
String rst4 = generateRandom();
String rst5 = generateRandom();
String rst6 = generateRandom();
String rst7 = generateRandom();
String rst8 = generateRandom();
String rst9 = generateRandom();
String rst10 = generateRandom();
private static String generateRandom() {
String aToZ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
Random rand = new Random();
StringBuilder res=new StringBuilder();
for (int i = 0; i < 17; i++) {
int randIndex=rand.nextInt(aToZ.length());
res.append(aToZ.charAt(randIndex));
}
return res.toString();
}
}
您的GC正在删除对象,因为您没有缓存它们,因此尝试将它们缓存为一个List而不是每次都创建一个新对象并分配给局部变量,这可能引发异常。
public static void main(String[] args){
try {
long count = 0;
List<A> list = new ArrayList<A>();
for (;;) {
list.add(new A());
count++;
if (count % 100 == 0) {
System.out.println("Created " + count);
}
}
} catch (Exception ex) {
System.out.println("Exception occured");
System.out.println(ex);
}
}
线程“主”中的异常java.lang.OutOfMemoryError:javaapplicationlang.javaApplication3处java.lang.String.valueOf(String.java:3113)处java.lang.Long.toString(Long.java:399)处的Java堆空间。 main(JavaApplication3.java:34)C:\\ Users \\ Ayat Abu Khadrah \\ AppData \\ Local \\ NetBeans \\ Cache \\ 8.2 \\ executor-snippets \\ run.xml:53:Java返回:1
enter code here
BUILD FAILED(总时间: 5分5秒)
如果您不想玩List,可以使用
public static void main(String[] args){
try {
long count = 0;
A current = new A();
for (;;) {
current.next = new A();
current = current.next;
count++;
if (count % 100 == 0) {
System.out.println("Created " + count);
}
}
} catch (Exception ex) {
System.out.println("Exception occured");
System.out.println(ex);
}
}
class A {
A next;
.
.
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.