0 0

Java 内存泄漏问题10

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

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

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);
      }
 } 

2013年4月09日 20:36
  • 大小: 75.5 KB
  • 大小: 72.4 KB

3个答案 按时间排序 按投票排序

0 0

采纳的答案

看你的截图,有153个对象在每隔60秒调用一次缓存更新,也就是说有153个Key.

你的线程池只有25个,可能就排到delayQueue上去了,解决方案就是增加线程池的大小,而且你这个线程根据key只会增加不会减少。

所以想要彻底解决问题,需要重新设计缓存的方案.

2013年4月11日 09:37
0 0

没有太明白你要想做什么.
提示一点吧:
每调用一次getResult这个方法的时候!cacheMap.containsKey(mapKey)都会启一个线程.

      pool.scheduleAtFixedRate(new Runnable() { 
 
        @Override 
        public void run() { 
 
          Object obj = dataManager.getResult(methodName, parameterMap); 
          cacheMap.put(mapKey, obj); 
 
         } 
       }, 0, timeLimited, TimeUnit.SECONDS); 

线程数量会不断增加。没有释放?

2013年4月10日 14:36
0 0

改成下面的代码

public class CachedDataManager extends DataManagerDecorator {

  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();

    Object obj=cacheMap.get(mapKey);
    if (obj!=null) {
          obj = dataManager.getResult(methodName, parameterMap);
          cacheMap.put(mapKey, obj);
     }
     return obj;
   }
} 
/*
使用线程池更慢,实际上在一个线程内减少了线程切换和创建的开销,性能更好一些。
你说的没有立即执行就是因为线程切换。
实际上线程任务一旦提交就在执行了,只是在线程任务完成put之前母线程就get,所以你在47行得不到。
*/

2013年4月09日 22:38

相关推荐

    java内存泄漏问题追踪

    Java内存泄漏问题追踪 在Java编程中,内存泄漏是一个严重的问题,它会导致程序性能下降,甚至可能导致应用程序崩溃。内存泄漏是指程序在申请内存后,无法释放已不再使用的内存空间,随着时间推移,系统可用内存逐渐...

    关于JAVA内存泄漏问题注意事项

    Java内存泄漏问题是一个重要的主题,尤其对于大型的J2EE应用程序而言,理解并避免内存泄漏至关重要。虽然Java的垃圾收集机制能自动管理内存,但并不意味着程序员可以完全忽视内存管理。以下是一些关于Java内存泄漏的...

    JAVA内存泄漏问题处理方法经验总结

    这篇博客“JAVA内存泄漏问题处理方法经验总结”分享了作者在处理此类问题时的一些实用技巧和经验,结合源码分析和工具使用,对于Java开发者来说是非常有价值的。 首先,了解内存泄漏的基本概念是至关重要的。内存...

    关于java内存泄露问题解决

    ### 关于Java内存泄露问题解决 #### 引言:Java内存管理的核心——垃圾回收机制(GC) Java作为当今产业界和学术界最炙手可热的编程语言之一,以其独特的安全性和可移植性赢得了广泛的应用,尤其是在服务器端编程...

    如何解决Java内存泄漏

    Java内存泄漏是软件开发中一个常见的问题,它不仅会影响应用程序的性能,还可能导致系统崩溃。通过深入了解Java的内存管理机制,并借助于专业的工具如OptimizeIt,可以有效地检测和解决内存泄漏问题。此外,开发者还...

    java内存泄漏解决

    本文将详细介绍如何解决Java内存泄漏问题,帮助开发者更好地理解和应对这一挑战。 #### 二、Java内存模型与内存区域 Java虚拟机(JVM)管理着多种不同类型的内存区域,包括堆内存(Heap Memory)、方法区(Method Area)...

    java内存泄露、溢出检查方法和工具

    Java内存管理是开发Java应用程序时的关键环节,内存泄露和溢出问题可能导致系统性能下降,甚至导致服务崩溃。本文将深入探讨如何检测和分析Java内存泄露与溢出,并介绍一种常用的工具——Memory Analyzer(MAT)。 ...

    Java内存泄露_JVM监控工具介绍

    为了检测和解决Java内存泄露问题,Java提供了多种工具和命令来帮助开发者快速地定位和解决问题。本文将介绍Java内存泄露的相关知识点和JVM监控工具的使用方法。 一、jstack命令 jstack命令是一个强大的工具,用于...

    java内存泄漏分析工具

    Java内存泄漏是一个严重的问题,它会导致程序性能下降,甚至可能导致应用程序崩溃。为了有效地诊断和解决这类问题,开发者需要借助特定的分析工具。本篇将详细探讨Java内存泄漏及其相关的分析工具。 内存泄漏是指...

    Java内存泄漏问题相关总结

    【Java内存泄漏问题相关总结】 在Java编程中,内存泄漏是一个严重的问题,它指的是程序中已分配的内存没有被正确地释放,导致这部分内存无法被垃圾收集器(GC)回收,长时间积累会消耗大量系统资源,影响应用性能。...

    如何解决Java内存泄漏.pdf

    Java内存泄漏是一个开发者在开发和维护Java应用程序时必须面对的问题。内存泄漏会导致程序占用越来越多的内存资源,从而影响性能,甚至导致程序崩溃。本文将深入讨论Java内存泄漏的解决方法,提供一些工具和技巧,...

    java内存分析-内存泄露问题.rar

    本文将深入探讨Java内存分析和内存泄露问题。 首先,我们需要了解Java内存模型的基础。Java内存主要分为三个区域:堆(Heap)、栈(Stack)和方法区(Method Area)。堆用于存储对象实例,栈用于存储方法调用及局部...

    JAVA内存泄漏分析工具

    "JAVA内存泄漏分析工具"正是一款用于解决此类问题的专业工具,它能帮助开发者定位并修复内存相关的问题,如内存泄漏和内存溢出。 内存泄漏是程序在申请内存后,无法释放已申请的内存空间,一次小的内存泄漏可能看似...

    内存泄漏问题\防范JAVA内存泄漏解决方案

    在Java编程中,内存泄漏是一个严重的问题,尤其对于长时间运行的应用程序,它可能...通过细心的代码审查、合理的对象管理和利用工具进行监控,我们可以有效地避免和解决Java内存泄漏问题,从而确保应用的稳定性和性能。

    Java内存泄漏问题处理方法经验总结

    Java内存泄漏问题处理方法经验总结 Java内存泄漏问题处理方法经验总结是Java开发中非常重要的一个方面,今天我们将分享关于Java内存泄漏问题处理方法经验总结的知识点。 首先,Java内存泄漏的问题描述是系统在...

    java内存泄露总结

    Java内存泄露问题是软件开发过程中常见的难题之一。通过对内存管理机制的理解及上述几种常见内存泄露场景的认识,开发者可以更好地预防和解决这类问题。为了进一步提高代码的质量,建议在开发过程中结合单元测试和...

    java内存泄露分析工具 eclipse3.5插件

    通过MAT插件,你可以定位到那些持有大量内存但本应被释放的对象,从而修复内存泄露问题。同时,MAT还会提供一些优化建议,帮助你改进代码,减少不必要的内存消耗。 总之,"java内存泄露分析工具 eclipse3.5插件"是...

    Java内存泄露及内存无法回收解决方案

    4. Native内存泄漏:Java应用可能使用JNI(Java Native Interface)与C/C++代码交互,若C/C++部分存在内存泄漏,也会间接导致Java内存泄漏。 解决内存泄漏的方法主要包括: 1. 使用工具监控:通过工具如VisualVM、...

Global site tag (gtag.js) - Google Analytics