java使用局部線程池導致的泄露問題

局部線程池使用不當會導致OutOfMemoryError。

內存泄露的代碼:

public class JVMDemoTest {
	public static void main(String[] args) throws Exception {
        JVMDemoTest t = new JVMDemoTest();
        while (true) {
            Thread.sleep(1000);
            t.test();
        }
    }

    private void test() {
        for (int i = 0; i < 10; i++) {
        	ExecutorService  mExecutors = Executors.newFixedThreadPool(3);
            for (int j = 0; j < 3; j++) {
                mExecutors.execute(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("execute");
                    }
                });
            }
        }
    }
}

報錯信息:

java.lang.OutOfMemoryError: unable to create new native thread
	at java.lang.Thread.start0(Native Method)
	at java.lang.Thread.start(Thread.java:717)
	at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:957)
	at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1367)
	at jvmTest.JVMDemoTest.test(JVMDemoTest.java:20)
	at jvmTest.JVMDemoTest.main(JVMDemoTest.java:12)

內存如下:

線程如下(在拐點處報錯):

 

如果加入線程池執行shutdown方法。

public class JVMDemoTest {
	public static void main(String[] args) throws Exception {
        JVMDemoTest t = new JVMDemoTest();
        while (true) {
            Thread.sleep(1000);
            t.test();
        }
    }

    private void test() {
        for (int i = 0; i < 10; i++) {
        	ExecutorService  mExecutors = Executors.newFixedThreadPool(3);
            for (int j = 0; j < 3; j++) {
                mExecutors.execute(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("execute");
                    }
                });
            }
            stop(mExecutors);
        }
    }
    
    public void stop(ExecutorService  mExecutors){
        if (mExecutors != null) {
        	mExecutors.shutdown();
        	try {
				mExecutors.awaitTermination(200 * 3, TimeUnit.SECONDS);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
            for (int i = 0; i < 10 && !mExecutors.isTerminated(); i++) {
                try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
            }
        }

    }
}

內存如下:

線程池如下:

參考文章:

https://cloud.tencent.com/developer/article/1579107

https://www.cnblogs.com/Shock-W/p/9835469.html

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章