静态多层Map缓存清除

最近重构项目遇到一个问题。一个本地缓存的Map凌晨定时清除数据,但好几天了都没清除。内存累加,执行500W的数据会增长将近2.86G的内存,虽然暂时服务器还够用,不过感觉总有一天会挂掉。

启动时内存占用:

PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                                   
81159 root      20   0 28.951g 1.320g  14724 S   0.0  1.1   0:12.76 java   

执行500W数据后的内存占用:

 PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                                   
 81159 root      20   0 33.399g 4.186g  14956 S   0.0  3.3  14:14.34 java 

Map定义如下:

public static Map<Integer, Map<Long, List<Long>>> USER_REPEAT = new ConcurrentHashMap<Integer, Map<Long, List<Long>>>();

百度了一下解决方法,说静态变量无法被GC,而且如果有地方引用也不会回收。不过new的对象可以被回收。
第一种,调用clear()方法后设置map=null;

USER_REPEAT.clear();
USER_REPEAT=null;

第二种,循环删除;

for (Map.Entry<Integer, Map<Long, List<Long>>> entry : USER_REPEAT.entrySet()) {
    USER_REPEAT.remove(entry.getKey());
}

测试上面两张方法后GC,内存无明显变化。
想了一下是不是可能两层嵌套的原因。写了个循环删除。果然删除后内存有明显的变化。

Map<Long, List<Long>> subMap = null;
for (Integer key : USER_REPEAT.keySet()) {
    subMap = USER_REPEAT.get(key);
    for (Long subKey : subMap.keySet()) {
        subMap.remove(subKey);
    }
    USER_REPEAT.remove(key);
}

测试95W简单数据内存变化
监控堆从163M降到10M

分析了下原因应该是直接删除key但是没有删除子Map中对List的引用,导致内存不释放。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值