JavaGC对此有何反应?
我正在开发Java应用程序,它是一个后端应用程序。该应用程序需要逐个处理某些XML文件(SAX,来自“dom4j”的SaxReader)。处理XML有以下步骤: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
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) 但接下来,我必须深入研究并重新传递地图,直到它到达需要的地方:(