[心缘地方]同学录
首页 | 功能说明 | 站长通知 | 最近更新 | 编码查看转换 | 代码下载 | 常见问题及讨论 | 《深入解析ASP核心技术》 | 王小鸭自动发工资条VBA版
登录系统:用户名: 密码: 如果要讨论问题,请先注册。

[备忘]java.util.zip.Inflater未关闭导致的内存持续增长,内存占用超过-Xmx的限制

上一篇:[备忘]logback关闭mongo的debug日志
下一篇:[备忘]linux下,修改nginx和tomcat的backlog设置

添加日期:2017/10/16 15:41:59 快速返回   返回列表 阅读4120次
现象,tomcat的内存持续飙升,超过-Xmx的限制大小很多,

服务器报警,某tomcat定义的-Xmx是10G,但实际占用了26G内存,超的太TM多了。

想到的可能:jvm本身需要内存,线程需要额外内存,native本地库内存,-Xmx其实只是定义了堆内存,不包括前面这几个。

(1)用
jmap -dump:format=b,file=/data/query5.bin 进程pid
做了dump文件,文件只有7G

(2)用mat分析,看到实际占用内存,只有310多M,
看HistogramFenix,其中
java.lang.ref.Finalizer 占用276MB
java.util.zip.Inflater 占用255MB

(3)
搜索,

Java的Finalizer引发的内存溢出
http://www.cnblogs.com/benwu/articles/5812903.html

可知,大量的Finalizer可能引起内存溢出,源头是谁?

(4)
java.util.zip.Inflater是gzip解压的一个类,搜索得知

它会调用本地native类,会分配C的堆内存,

必须调用它的end方法,否则C的堆内存不释放,会持续增长。

看工程代码,关于zip的,有此方法:


public static String unCompressStr(byte[] bytes) throws IOException {
    ByteArrayOutputStream out = new ByteArrayOutputStream(bytes.length);
    ByteArrayInputStream in = new ByteArrayInputStream(bytes);
    GZIPInputStream gunzip = new GZIPInputStream(in);
    byte[] buffer = new byte[bytes.length];
    int n;
    while ((n = gunzip.read(buffer)) >= 0) {
        out.write(buffer, 0, n);
    }
    return out.toString("UTF-8");
}



看看,输入流没有关闭,加上gunzip.close(),它会逐层的关闭流,也就关闭了底层的Inflater。

问题解决。
 

评论 COMMENTS
没有评论 No Comments.

添加评论 Add new comment.
昵称 Name:
评论内容 Comment:
验证码(不区分大小写)
Validation Code:
(not case sensitive)
看不清?点这里换一张!(Change it here!)
 
评论由管理员查看后才能显示。the comment will be showed after it is checked by admin.
CopyRight © 心缘地方 2005-2999. All Rights Reserved