Java 理论与实践:用弱引用堵住内存泄漏
作者:网络转载 发布时间:[ 2012/7/26 11:03:26 ] 推荐标签:
public class MapLeaker {
public ExecutorService exec = Executors.newFixedThreadPool(5);
public Map
= Collections.synchronizedMap(new HashMap
private Random random = new Random();
private enum TaskStatus { NOT_STARTED, STARTED, FINISHED };
private class Task implements Runnable {
private int[] numbers = new int[random.nextInt(200)];
public void run() {
int[] temp = new int[random.nextInt(10000)];
taskStatus.put(this, TaskStatus.STARTED);
doSomeWork();
taskStatus.put(this, TaskStatus.FINISHED);
}
}
public Task newTask() {
Task t = new Task();
taskStatus.put(t, TaskStatus.NOT_STARTED);
exec.execute(t);
return t;
}
}
图 1 显示 MapLeaker GC 之后应用程序堆大小随着时间的变化图。上升趋势是存在内存泄漏的警示信号。(在真实的应用程序中,坡度不会这么大,但是在收集了足够长时间的 GC 数据后,上升趋势通常会表现得很明显。)
图 1. 持续上升的内存使用趋势
确信有了内存泄漏后,下一步是找出哪种对象造成了这个问题。所有内存分析器都可以生成按照对象类进行分解的堆快照。有一些很好的商业堆分析工具,但是找出内存泄漏不一定要花钱买这些工具 —— 内置的 hprof 工具也可完成这项工作。要使用 hprof 并让它跟踪内存使用,需要以 -Xrunhprof:heap=sites 选项调用 JVM。
清单 3 显示分解了应用程序内存使用的 hprof 输出的相关部分。(hprof 工具在应用程序退出时,或者用 kill -3 或在 Windows 中按 Ctrl+Break 时生成使用分解。)注意两次快照相比,Map.Entry、Task 和 int[] 对象有了显著增加。
清单 3. HPROF 输出,显示 Map.Entry 和 Task 对象的增加
SITES BEGIN (ordered by live bytes) Fri Oct 28 16:30:48 2005
percent live alloc'ed stack class
rank self accum bytes objs bytes objs trace name
1 70.13% 70.13% 5694888 13909 5694888 13909 300305 int[]
2 18.27% 88.40% 1483976 68 278273632 13908 300321 int[]
3 4.11% 92.51% 333816 13909 333816 13909 300310 java.util.HashMap$Entry
4 2.74% 95.25% 222544 13909 222544 13909 300304 com.quiotix.dummy.MapLeaker$Task
5 2.42% 97.67% 196640 2 262192 11 300325 java.util.HashMap$Entry[]
6 0.66% 98.33% 53680 3355 222464 13904 300324 java.util.concurrent.LinkedBlockingQueue$Node
SITES END
SITES BEGIN (ordered by live bytes) Fri Oct 28 16:31:32 2005
percent live alloc'ed stack class
rank self accum bytes objs bytes objs trace name
1 77.07% 77.07% 41176024 100020 41176024 100020 301069 int[]
2 12.98% 90.05% 6933768 359 2001885688 100020 301093 int[]
3 4.49% 94.55% 2400480 100020 2400480 100020 301082 java.util.HashMap$Entry
4 3.00% 97.54% 1600320 100020 1600320 100020 301068 com.quiotix.dummy.MapLeaker$Task
5 1.96% 99.50% 1048592 1 2097248 14 301104 java.util.HashMap$Entry[]
6 0.05% 99.55% 25936 1621 1600240 100015 301101 java.util.concurrent.LinkedBlockingQueue$Node
SITES END
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11