JavaGC对此有何反应?

JavaGC对此有何反应?,java,memory-management,memory-leaks,hashmap,Java,Memory Management,Memory Leaks,Hashmap,我正在开发Java应用程序,它是一个后端应用程序。该应用程序需要逐个处理某些XML文件(SAX,来自“dom4j”的SaxReader)。处理XML有以下步骤: 从磁盘加载XML文件 从数据库中填充HashMap单例 使用来自单例的数据处理XML文件 清除居住的单身人士 在重复这个过程之前先睡10秒钟 我使用的Hashmap单例如下所示: public class SomeMap { private static SomeMap instance; public static

我正在开发Java应用程序,它是一个后端应用程序。该应用程序需要逐个处理某些XML文件(SAX,来自“dom4j”的SaxReader)。处理XML有以下步骤:

  • 从磁盘加载XML文件
  • 从数据库中填充HashMap单例
  • 使用来自单例的数据处理XML文件
  • 清除居住的单身人士
  • 在重复这个过程之前先睡10秒钟
  • 我使用的Hashmap单例如下所示:

    public class SomeMap {
    
        private static SomeMap instance;
        public static SomeMap getInstance() {
            if(instance == null)
                instance = new SomeMap();
            return isntance;
        }
    
        private HashMap<String, ArrayList<SomeObject>> actualMap;
    
        private SomeMap() {
            clear();
        }
    
        public void clear() {
            if(actualMap != null)
                actualMap.clear();
            actualMap = new HashMap<String, ArrayList<SomeObject>>();
        }
    
        ...
        //fill method also calls "clear" before populating new values.
        ...
    
        public SomeObject getSomeObject(String key, String otherCriteria) {
            //for-each loop that obtains specific SomeObject belonging to "key" in the map and having "otherCriteria".
            return foundSomeObject;
        }
    }
    
    公共类SomeMap{
    私有静态SomeMap实例;
    公共静态SomeMap getInstance(){
    if(实例==null)
    instance=newsomemap();
    回报率;
    }
    私有HashMap-actualMap;
    私有映射(){
    清除();
    }
    公共空间清除(){
    如果(实际映射!=null)
    actualMap.clear();
    actualMap=新HashMap();
    }
    ...
    //fill方法在填充新值之前也会调用“clear”。
    ...
    公共SomeObject getSomeObject(字符串键、字符串其他条件){
    //对于每个获得属于映射中“key”且具有“otherCriteria”的特定SomeObject的循环。
    返回foundSomeObject;
    }
    }
    
    现在,步骤3调用项目的另一部分,该部分根据单例中的“SomeObject”值执行某些计算(单例存在是为了防止不断查找数据库,因为单例中的数据仅用于读取)。 我每次都需要重新加载单例,因为在处理2个XML文件之间,DB参数可能会发生一些变化

    问题是,我注意到我的软件在工作时占用了越来越多的内存。变化并不是很大,我每处理500个文件就获得1 MB,但由于我每天必须处理大约40000个文件,后端应该连续工作几天,所以我很担心。 整个软件从100MB的ram使用开始,经过几个小时的工作,大约达到300 MB。 我不能发布整个项目,因为它是巨大的,但我感觉问题可能与我使用的单例有关


    你认为我的单例设计/使用是错误的还是内存泄漏可能在代码中的其他地方?

    我认为你发布的代码中没有内存泄漏。当堆耗尽并且即将分配新内存时,GC将启动。您可以使用
    java-Xmx128m
    将堆设置为较小的大小,比如128Mb;几小时后应该不会再达到300了。一切可能都很好。如果需要,GC将收集。如果它有足够的空闲内存,就没有问题。但是您的单例是在Java中重新引入有害的全局变量的一种令人讨厌的方式。它使您的代码不可能是多线程的,很难进行测试,并促进了意大利面条式的代码。为什么不每次创建一个新的HahMap,并将其作为参数传递给step3方法?@JB Nizet,因为我不知道应用程序的哪个部分将来需要这些数据。我猜这些hashmap是自动创建的——就像我在项目中的任何地方打开DB连接一样,我猜使用全局单例可以模拟在任何需要的地方使用数据。毕竟,我认为这不是一个问题,因为数据是只读的,对于多个线程,我会使用ConcurrentHashMap:)错误不,你不会:线程1将其数据加载到singleton,而线程2加载其数据。。。给同一个单身汉。结果:数据已损坏:它可能是线程1的数据,或线程2的数据,或两者的混合,或一部分(因为一个线程可以清除它,而另一个线程可以填充它)。全球国家是邪恶的。将映射作为参数传递给需要它的方法。1)如果我将synchronize(this)放在clear()和fill()中会怎么样?这会挫败一个目标,因为单身汉将成为一个瓶颈,但会起作用,对吗?2) 但接下来,我必须深入研究并重新传递地图,直到它到达需要的地方:(