2011-04-19 61 views
0

我有一個Web應用程序,它通過每10秒運行一次調度程序任務將一些PCL文件轉換爲PDF。每次最多需要目錄中的20個文件並將它們轉換爲pdf。如何根據此統計數據改進java代碼?

前幾項任務運行良好,但一步一步變慢,突然出現GC overhead limit exceeded錯誤消息。

我試圖分析其與VisualVM的此內存泄漏,這裏是從堆轉儲一些輸出:enter image description here

很奇怪的是,字節情況下3.366.687!)這樣的量是所示。在應用程序中,我也有Streams,我真的檢查過這些流是否在相關操作完成時關閉。

我在三個方法中使用一個類中的字節: byte [] buf = new byte [1024];

public void initBuf() { 
     if (buf != null) { 
      for (int i = 0; i < buf.length; i++) { 
       buf[i] = (byte) 0x00; 
      } 

      pdf_y = PageSize.A4.getHeight(); 
     } 
    } 

public void appendBuf(char ch) { 

     if (ch == '\n') { 
      processChunk(); 
      drawChunks(); 
      pdf_newline(); 
     } else if (ch != '\r') { 
      buf[buf_index++] = (byte) (0xff & ch); 
     } 
    } 

    public void resetBuf() { 
     for (int i = buf_index; i >= 0; i--) { 
      buf[i] = (byte) 0x00; 
     } 

     buf_index = 0; 
    } 

你會在哪建議我看看? 我怎樣才能真正識別出我的哪些代碼正在做這些傷害?

我無法發佈所有的代碼,因爲有更多的類來做這種轉換,但我真的希望你能幫我一些建議becauise我花了很多時間,仍然這個內存問題仍然存在。

在此先感謝

+0

你試過了什麼? (有可能你可以看到一些改進,通過積極地將你要求的遊蕩的大字節數組取代它們) – 2011-04-19 19:30:29

回答

2

你的分析器的屏幕截圖顯示java.lang.Byte的的330萬個實例不的byte []。我會在其他地方尋找字節的使用情況(可能包括從字節自動裝箱以將它們插入到集合中的實例)。

我的第一個懷疑的是,你的代碼的其他部分是增加字節字節實例地圖(無論是作爲鍵或值),並沒有將其刪除,當他們不再需要。但這只是一個基於追蹤我自己的一些內存泄漏的猜測。

+0

至少如果我能夠在VM中找到這是使用字節做這些事情的類。 .. – 2011-04-19 20:15:53

+0

另請注意,您有301個字節[]的實例,共同佔用212 MB的內存。您可能會搜索代碼以查找Byte [],或者通過引用VisualVM中的Byte []數組來追溯。 – AaronD 2011-04-19 20:42:43

1

查看有關使用堆轉儲的VisualVM指南:here's Oracle's

您也可能會尋找NetBeans引用,因爲組件是相同的,例如, How do you find memory leaks using the Netbeans profiler?

您需要知道是誰創建或保留對那些Byte[] s和Byte s的引用。一個攻擊計劃是檢查各個Byte[]實例(「實例視圖」)並查看其參考。 「最近的GC根目錄」選項將顯示保留延遲Byte[]的一個對象路徑。

+0

問題是,如果我按下一個字節[]實例,我看到在右側的引用,但我只看到[](數組類型)和o(對象類型),沒有GC根箭頭爲我的變量... – 2011-04-19 21:12:34

+0

「顯示最近GC根「是一個選項,右鍵單擊上下文菜單。如果沒有GC根目錄,則表示該對象符合GC要求。 – 2011-04-19 22:55:24