Hibernate - 搜索 - Java堆空间

时间:2011-05-16 14:10:24

标签: java hibernate heap-memory

我有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:

  • 注册表1:750283136。
  • Registry 10000:648229608。
  • Registry 50000:411171048。
  • 注册表100000:Java堆空间。

如何修复java堆空间问题? 我知道问题是当我检查iObject是否存在时。

3 个答案:

答案 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吗?