iteye_16970
2013-04-09 20:36
浏览 408
已采纳

Java 内存泄漏问题

因为系统有内存泄露问题,导致频繁的Full GC,用jmap将内存使用情况dump下来,然后通过mat分析了一下,发现是由于缓存map和更新该map的线程池导致的,截图见附件,下面这个是涉及到的类,研究了好几天这个问题,现在终于定位到具体的代码,耐于经验有限,想请教一下大家都是怎么处理系统中缓存数据的,有闲暇时间的帮看下下面的代码应该如何修改。。

还有个问题就是,定时更新run()里的程序总是不会立即执行,scheduleAtFixedRate的第二个参数设为0也不管用,只有这次执行完,下次再走这儿时cacheMap里才有上次的数据。所以只好在外面再执行一遍,总觉得这么写很奇怪

[code="java"]
public class CachedDataManager extends DataManagerDecorator {

private static ScheduledExecutorService pool;
private long timeLimited;//缓存中数据更新间隔时间 60s
private int poolSize;//线程池大小,20
private static int cacheSize;
public static Map cacheMap;// = new HashMap();

public Object getResult(final String methodName, final Map parameterMap) {

if (cacheMap == null) {
  synchronized (CachedDataManager.class) {
    if (cacheMap == null) {
      cacheMap = new ConcurrentLinkedHashMap.Builder()
             .maximumWeightedCapacity(cacheSize).build();
   }
 }
}

// 根据HashCode生成缓存map的key
final String mapKey = new KeyCreater(methodName, parameterMap)
                   .getHashCode();

// 缓存中没有该条数据则放入有定时更新策略的线程池
if (!cacheMap.containsKey(mapKey)) {

  if (pool == null) {
     pool = Executors.newScheduledThreadPool(poolSize);
  }
  pool.scheduleAtFixedRate(new Runnable() {

    @Override
    public void run() {

      Object obj = dataManager.getResult(methodName, parameterMap);
      cacheMap.put(mapKey, obj);

     }
   }, 0, timeLimited, TimeUnit.SECONDS);
 } else if (cacheMap.get(mapKey) != null) {
   return cacheMap.get(mapKey);
 }
            //因为上面的不会立即执行,所以第一次查询执行这里
  Object obj = dataManager.getResult(methodName, parameterMap);
  cacheMap.put(mapKey, obj);

  return cacheMap.get(mapKey);
  }

}

[/code]

3条回答 默认 最新

相关推荐 更多相似问题