2011-05-16 67 views
1

因爲我在mi代碼中添加修改,所以我有一個hibernate的java堆空間問題。 從文本文件(2GB)程序負載信息休眠 - 搜索 - Java堆空間

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.
  • 註冊表10000:648229608.
  • 註冊表50000:411171048.
  • 註冊表100000:Java堆空間。

我該如何解決java堆空間問題? 我知道問題是當我檢查iObject是否存在。

+1

那麼,你的問題是什麼呢? – buruzaemon 2011-05-16 14:18:26

+0

我該如何解決java堆空間問題? – JMira 2011-05-16 14:28:13

回答

3

您需要一個flush()後跟一個clear()flush()只會將任何掛起的更新推送到數據庫。 clear()從會話中刪除對象。儘管如此,您需要注意clear(),因爲任何其他代碼對參與會話中的對象的引用都具有「分離」對象。

+0

這提高了性能很多,我正在運行一些測試,但我認爲這解決了我的問題。 – JMira 2011-05-16 15:23:35

0

您聲明BufferedReader input,但您似乎永遠不會使用它。難道你在while循環中引用的line對象是以非緩衝方式訪問底層File

+0

是的,我不把整個代碼,因爲真的很大,但我使用:line = input.readLine();訪問文本文件。 – JMira 2011-05-16 15:07:36

+0

文件是否包含行終止字符('\ n'或'\ r')? – 2011-05-16 15:10:31

+0

是的,問題是沒有讀取文件,我拿出檢查賬戶是否存在的代碼,並且內存性能很好。 – JMira 2011-05-16 15:15:34

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

注意,這可能發生,即使你因爲像split這樣的常用方法可能是負責任的,所以請不要明確請致電subString

+0

問題是沒有讀取文件,我拿出檢查帳戶是否存在的代碼,並且內存性能很好。任何方式我都會檢查字符串,謝謝! – JMira 2011-05-16 15:17:11

+0

@JMira檢查賬號是否存在的代碼是否調用'line'上的'split'或'subString',並保留某些集合中的結果? – 2011-05-16 15:21:46