我有hibernate的java堆空间问题,因为我在mi代码中添加了一个修改。 程序从文本文件(2GB)
加载信息BufferedReader input = new BufferedReader(new FileReader(file));
while (line.compareTo(EOF) != 0) {
//Load of infoObject, lots of parse information from the text file
//Read lines of text using: line = input.readLine();
getSession().save(infoObject);
counter++;
if (counter % 100 == 0) {
getSession().flush();
System.gc();
}
}
这项工作很棒,现在如果我的数据库中已存在infoObject,我需要更新记录,我用这个:
BufferedReader input = new BufferedReader(new FileReader(file));
while (line.compareTo(EOF) != 0) {
//Load of infoObject
iObject infoObject_tmp = new iObject();
infoObject_tmp.setNumAccount(numAccount);
infoObject_tmp.setCloseDate(new Date("02/24/2011"));
iObject infoObject_search = (iObject) getSession().load(iObject.class, infoObject_tmp);
if (infoObject_search !=null){
getSession().update(infoObject);
}else{
getSession().save(infoObject);
}
counter++;
if (counter % 100 == 0) {
getSession().flush();
System.gc();
}
}
FreeMemory:
如何修复java堆空间问题? 我知道问题是当我检查iObject是否存在时。
答案 0 :(得分:3)
您需要flush()
后跟clear()
。 flush()
仅将任何挂起的更新推送到数据库。 clear()
从会话中删除对象。但是你需要注意clear()
,因为任何其他代码都会引用会话中的对象现在有一个“分离”对象。
答案 1 :(得分:1)
如果没有看到更多代码,很难说清楚到底发生了什么。由于您的BufferedReader
似乎没有被使用,因此也有点令人困惑。
那就是说,考虑到你正在做的事情,一种可能性就是你在某些文本输入上调用substring
并保持对作为一个文本输入返回的String
对象的引用。结果。例如,你可能会做这样的事情:
List<String> allMySubstrings = new ArrayList<String>();
while((line = input.readLine()) != null){
String mySubstring = line.subString(40, 42);
// mySubstring still has a reference to the whole character array from line
allMySubstrings.add(mySubstring);
}
您可能会认为您只会引用allMySubstrings
,而不会引用所有line
。但是,由于实施subString
的方式,生成的String
对象将引用line
中的整个原始字符数组,而不仅仅是相关的子。垃圾收集不会像您期望的那样发生
如果您这样做,可以通过创建新的String object
:
List<String> allMySubstrings = new ArrayList<String>();
while((line = input.readLine()) != null){
String mySubstring = new String(line.subString(40, 42));
allMySubstrings.add(mySubstring);
}
请注意,即使您没有明确调用subString
,也可能会发生这种情况,因为split
等常见方法可能会受到回应。
答案 2 :(得分:0)
您声明BufferedReader input
,但您似乎永远不会使用它。可能是您在line
循环中引用的while
对象是以非缓冲方式访问基础File
吗?