论坛首页 Java企业应用论坛

利用dump heap找出内存泄漏。

浏览 6992 次
精华帖 (0) :: 良好帖 (5) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-08-27  
  今日在resin的dump heap中发现大量的char[]和byte[]对象:

引用

1.0000 112.922M 7.613M 105.309M 166308 java.util.HashMap
0.8115 97.763M 97.763M 0.000M 483874 char[]
0.7928 89.842M 89.842M 0.000M 15243 byte[]

0.7869 88.862M 16.175M 72.687M 706694 java.util.HashMap$Entry
0.5190 58.608M 11.225M 47.382M 490447 java.lang.String
0.3688 41.640M 9.187M 32.453M 170271 java.util.HashMap$Entry[]
0.2521 28.465M 0.021M 28.444M 455 com.caucho.db.store.ReadBlock


  加起来竟然有200M之大,马上就想起了一个低层的截字符串的函数使用了byte[]和char[],而且使用率非常频繁,平均每个页面都会调用100-150次左右。

	public static String subContentStringOrial(String str, int targetCount,String more)
	{
		if (str == null)
			return "";
		int initVariable = 0;
		StringBuffer restr = new StringBuffer();
		if (str.length() <= targetCount)
			return str;
		String s1=null;
		byte[] b;
		char[] tempchar = str.toCharArray();
		for (int i = 0; (i < tempchar.length && targetCount > initVariable); i++) {
			s1 = String.valueOf(tempchar[i]);
			b = s1.getBytes();
			initVariable += b.length;
			restr.append(tempchar[i]);
		}
		if (targetCount == initVariable || (targetCount == initVariable - 1)) {
			restr.append(more);
		}
		return restr.toString();
	}


  发现byte[] b和char[] tempchar 使用完后没有释放(本人不太相信GC),手动释放一下,在return 前加:
		b = null;
		tempchar = null;
		s1=null;


引用

1.0000 112.989M 7.625M 105.364M 166567 java.util.HashMap
0.7867 88.893M 16.189M 72.704M 707325 java.util.HashMap$Entry
0.5333 60.252M 60.252M 0.000M 497341 char[]
0.5281 59.665M 11.515M 48.151M 503080 java.lang.String
0.4842 54.709M 54.709M 0.000M 17755 byte[]
0.3689 41.682M 9.209M 32.473M 170534 java.util.HashMap$Entry[]


重构后虽然变小了,但也很大。不知道是哪个地方使用了char[]和byte[],或者其它包使用了又没有释放。

   发表时间:2008-08-27  
推荐你看一下这个http://fly-hyp.iteye.com/blog/182582
其实tempchar = null对GC并没有帮助
0 请登录后投票
   发表时间:2008-08-27  
在一个方法里面的变量是不会引起内存泄露的。
内存泄露都是发生在类变量和实例变量(且此实例被缓存、如单例模式)里。
我建议你从HashMap、HashMap$Entry 入手查查。
我也研究过一阵子的内存泄露问题,最终解决了。
0 请登录后投票
   发表时间:2008-08-27  
SeanHe 写道
推荐你看一下这个http://fly-hyp.iteye.com/blog/182582
其实tempchar = null对GC并没有帮助


看过了。不过看了跟没有看一样。哈。
0 请登录后投票
   发表时间:2008-08-27  
就算系统执行了gc
[INFO ][memory ] 24190.256: parallel nursery GC 869440K->632640K (1048576K), 71.019 ms
这部份内存还是释放不了。

引用
1.0000 114.316M 7.795M 106.521M 170294 java.util.HashMap
0.7829 89.501M 16.504M 72.998M 721067 java.util.HashMap$Entry
0.7141 81.632M 81.632M 0.000M 707593 char[]
0.6617 75.643M 16.389M 59.254M 716066 java.lang.String
0.5828 66.625M 66.625M 0.000M 60001 byte[]
0.4126 47.171M 0.035M 47.137M 754 com.caucho.db.store.ReadBlock
0.3722 42.554M 9.701M 32.853M 175836 java.util.HashMap$Entry[]
0.2268 25.921M 7.605M 18.316M 332268 java.util.ArrayList
0.1852 21.172M 7.764M 13.408M 339205 org.mira.lucene.analysis.dict.a
0.1675 19.150M 18.259M 0.891M 338907 java.lang.Object[]
0.1580 18.065M 4.170M 13.895M 45547 com.caucho.server.dispatch.Invocation
0 请登录后投票
   发表时间:2008-08-27  
byte[]和char[]多是很正常的,凡是Java里面的String操作最终都会转化为char[]的,凡是IOStream的操作都会转化为byte[],所以看这个是看不出来的。

你要过滤一下系统类,重点检索应用程序自定义的类,HttpSession引用的类的数量变化。
0 请登录后投票
   发表时间:2008-08-27  
robbin 写道
byte[]和char[]多是很正常的,凡是Java里面的String操作最终都会转化为char[]的,凡是IOStream的操作都会转化为byte[],所以看这个是看不出来的。

你要过滤一下系统类,重点检索应用程序自定义的类,HttpSession引用的类的数量变化。



嗯,其实系统现在运行的很正常,load average: 0.21, 0.39, 0.31

只是担心会出问题。
0 请登录后投票
   发表时间:2008-08-27  
strongkill 写道
load average: 0.21, 0.39, 0.31

load 连1都不到,哪来的压力啊
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics