Exception 和 stack 溢出

如果我们程序中有太多关于exception 的处理,就有可能引起

 
Exception in thread "main" java.lang.StackOverflowError
at java.lang.Exception.<init>(Exception.java:66)
at java.lang.RuntimeException.<init>(RuntimeException.java:62)

因为Exception 的初始化和处理都有要对栈的操作,所以自然占栈的空间。

比如

public class ThreadTest {

    public static void main(String[]args){
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(0, 1, 5, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1), new ThreadPoolExecutor.AbortPolicy());
        List<String> imagesForTask =new ArrayList<String>();
        for(int i=0;i<100000;i++){
            imagesForTask.add("aaa");
        }
        scanRegistryImage(threadPool,0,imagesForTask);

    }
    private static void scanRegistryImage(final ThreadPoolExecutor threadPool,int idx, List<String> imagesForTask) {
        if (idx >= imagesForTask.size()) {
            return;
        }
        int current = idx;
        try {
            for (; current < imagesForTask.size(); current++) {
                System.out.println("current task :" + current + " is prepared to goin pool.");
                threadPool.execute(new ScanImageTask());
                System.out.println("current task :" + current + " is ok to goin pool.");
            }
        } catch (RejectedExecutionException e) {
            try {
                Thread.sleep(1);
                System.gc(); //如果这行不加,就会有栈溢出。
                System.out.println("scanRegistryImage has RejectedExecutionException with " + current + " so wait seconds, will do in next loop.");
                System.out.println("getActiveCount :"+threadPool.getActiveCount());
                System.out.println("getPoolSize :"+threadPool.getPoolSize());
                System.out.println("getTaskCount :"+threadPool.getTaskCount());
                scanRegistryImage(threadPool,  current, imagesForTask);
            } catch (Exception e1) {
                e1.printStackTrace();
            }

        }catch (Exception e) {
            e.printStackTrace();
            return;
        }
    }
}
public class ScanImageTask implements Runnable, Serializable {
	@Override
	public void run() {
		
		try {
            System.out.println("ScanImageTask start ##########################################################################################");
            Thread.sleep(100);
            System.out.println("ScanImageTask end ##########################################################################################");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

如果没有这行 System.gc(); 程序运行一半就会奔溃退出。

current task :86 is prepared to goin pool.
Exception in thread "main" java.lang.StackOverflowError
    at java.lang.Exception.<init>(Exception.java:66)
    at java.lang.RuntimeException.<init>(RuntimeException.java:62)
    at java.util.concurrent.RejectedExecutionException.<init>(RejectedExecutionException.java:64)
    at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2048)
    at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:821)
    at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1372)

猜你喜欢

转载自dmwdmc.iteye.com/blog/2259697
今日推荐