繁体   English   中英

设置Java Max堆大小不会在无限循环程序中引发任何错误

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM