论坛首页 Java企业应用论坛

生产环境jvm内存运行1小时,就接近xmx,系统奇慢。大量的jasperreport无法释放。

浏览 8357 次
精华帖 (0) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-10-20   最后修改:2011-10-21
http://www.iteye.com/topic/1116650?page=5#2262692

这个是前几天发的帖子,现在基本知道问题了。这个项目是一个政府项目,需要大量的打印功能,打印使用的是Jasperreport 3.7.0,客户端基于applet直接打印。有的功能,一天要打印200多次,所有的功能打印次数一天多在1000次以上。在jvm分配的内存要满的时候,保存了dump然后分析了一下,看到如下结果。但不能确认,大家帮给看看,到底是不时jasperreport的事,怎样解决。




堆中大量的JRBasePrintPage对象。

  • 大小: 55.5 KB
  • 大小: 20.3 KB
   发表时间:2011-10-20  
没使用过这个组件,但是对象大量存在说明组件资源没有释放,踏下心来看下使用的组件官网的文档,是不是使用完之后需要close掉得,自己的事情只有靠自己最可靠~
0 请登录后投票
   发表时间:2011-10-21  
Downgrade the Jasperreport to 2.0.5 and try again.
0 请登录后投票
   发表时间:2011-10-21  
每次打印的数据多吗?
我们这边也是用这个东西,但使用服务器生成PDF的,每天估计也有几千次打印,没出现过你的问题。服务器比政府的差多了。
0 请登录后投票
   发表时间:2011-10-21  
java_user 写道
每次打印的数据多吗?
我们这边也是用这个东西,但使用服务器生成PDF的,每天估计也有几千次打印,没出现过你的问题。服务器比政府的差多了。


你们用的是什么版本呀
0 请登录后投票
   发表时间:2011-10-21  
1.3,这个东西高版本不兼容低版本,懒得换了
0 请登录后投票
   发表时间:2011-10-21  
很明显了jasper缓存了大量数据,jasperprinter这个对象是不是一直缓存住,没有做clean up
0 请登录后投票
   发表时间:2011-10-21  
kakaluyi 写道
很明显了jasper缓存了大量数据,jasperprinter这个对象是不是一直缓存住,没有做clean up

不需要,直接创建一个新的得了
估计是楼主在将jasperprint输出到它的applet时没有关闭流吧
0 请登录后投票
   发表时间:2011-10-21  
java_user 写道
kakaluyi 写道
很明显了jasper缓存了大量数据,jasperprinter这个对象是不是一直缓存住,没有做clean up

不需要,直接创建一个新的得了
估计是楼主在将jasperprint输出到它的applet时没有关闭流吧


关了呀。

	public static void writeJasperPrint(HttpServletResponse response,
			JasperPrint jasperPrint) {
		// 输出jasperPrint对象
		//ResponseUtils.noCache(response);
		response.setContentType("application/octet-stream");
		ServletOutputStream ouputStream = null;
		ObjectOutputStream oos = null;
		try {
			ouputStream = response.getOutputStream();
			oos = new ObjectOutputStream(ouputStream);
			oos.writeObject(jasperPrint);
			oos.flush();
			oos.close();
			ouputStream.flush();
			ouputStream.close();
		} catch (IOException ex) {
			IoUtils.closeOutputStream(oos);
			IoUtils.closeOutputStream(ouputStream);
			throw new SystemException(ex);
		}
	}
0 请登录后投票
   发表时间:2011-10-21  
neptune 写道
java_user 写道
kakaluyi 写道
很明显了jasper缓存了大量数据,jasperprinter这个对象是不是一直缓存住,没有做clean up

不需要,直接创建一个新的得了
估计是楼主在将jasperprint输出到它的applet时没有关闭流吧


关了呀。

	public static void writeJasperPrint(HttpServletResponse response,
			JasperPrint jasperPrint) {
		// 输出jasperPrint对象
		//ResponseUtils.noCache(response);
		response.setContentType("application/octet-stream");
		ServletOutputStream ouputStream = null;
		ObjectOutputStream oos = null;
		try {
			ouputStream = response.getOutputStream();
			oos = new ObjectOutputStream(ouputStream);
			oos.writeObject(jasperPrint);
			oos.flush();
			oos.close();
			ouputStream.flush();
			ouputStream.close();
		} catch (IOException ex) {
			IoUtils.closeOutputStream(oos);
			IoUtils.closeOutputStream(ouputStream);
			throw new SystemException(ex);
		}
	}

我觉得应该是这里oos.writeObject(jasperPrint);  导致jasperPrint没有回收。
根据网上的说法,使用ObjectOutputStream会一直保持对你的对象的引用,垃圾回收器无法回收,时间长了自然会内存泄露。jasperreport这种东西本来对内存的要求就比较大,所以很容易短时间就发生了。
如果生成的文件不涉及安全性(防止拷贝),完全可以由服务器端生成PDF等格式,客户端不需要applet
0 请登录后投票
论坛首页 Java企业应用版

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