模拟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);
	}
}

你可能感兴趣的:(Java)