模擬ThreadLocal內存泄露(代碼實戰)

看了網上一大堆寫ThreadLocal內存泄露的文章,全都是概念和源碼內容,沒有一篇模擬內存泄露的文章。所以決定自己寫一個跟大家一塊討論學習。

/**
 * 模擬ThreadLocal內存泄露導致OOM
 * JVM啓動參數 -Xms20M -Xmx20M -Xmn10M
 * @param args
 */
public static void main(String[] args) {
	// 是否調用remove方法
	boolean doRemove = false;
	// 加鎖,讓多個線程串行執行,避免多個線程同時佔用內存導致的內存溢出問題
	Object lockObj = new Object();
	// 開啓20個線程
	ExecutorService executorService = Executors.newFixedThreadPool(20);
	// 爲了不重複使用線程,用Map標記一下已經已使用過的線程,
	Map<Long, Integer> threadIdMap = new ConcurrentHashMap<>();
	// 循環向線程變量中設置數據 1024 * 1024 = 1M
	for (int i = 0; i < 20; i++) {
		executorService.execute(() -> {
			synchronized (lockObj) {
				Integer num = threadIdMap.putIfAbsent(Thread.currentThread().getId(), 1);
				if (num == null) {
					ThreadLocal<Byte[]> threadLocal = new ThreadLocal<>();
					threadLocal.set(new Byte[1024 * 1024]);
					if(doRemove) {
						// 解決內存泄露關鍵
						threadLocal.remove();
					}
					// 將threadLocal置爲空引用,利於回收
					threadLocal = null;
					// 手工回收
					System.gc();
					try {
						// 調用GC後不一定會馬上回收
						Thread.sleep(500);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}

				System.out.println(Thread.currentThread().getName());
			}
		});
		// System.out.println(i);
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章