2014-07-16 83 views
0

我試圖從服務器向多個客戶端發送大塊文件。當我嘗試發送大小爲700mb的文件時,它顯示「OutOfMemory java heap space」錯誤。我正在使用Netbeans 7.1.2版本。 我也試過VMoption的屬性。但仍然會發生同樣的錯誤。我認爲讀取整個文件存在一些問題。以下代碼正在工作達300MB。請給我一些建議。內存不足java堆空間

在此先感謝

public class SplitFile { 
    static int fileid = 0 ; 

    public static DataUnit[] getUpdatableDataCode(File fileName) throws FileNotFoundException, IOException{ 

    int i = 0; 
    DataUnit[] chunks = new DataUnit[UAProtocolServer.singletonServer.cloudhosts.length]; 

    FileInputStream fis; 

    long Chunk_Size = (fileName.length())/chunks.length; 
    int cursor = 0; 

    long fileSize = (long) fileName.length(); 
    int nChunks = 0, read = 0;long readLength = Chunk_Size; 
    byte[] byteChunk; 

    try { 
     fis = new FileInputStream(fileName); 
     //StupidTest.size = (int)fileName.length(); 
     while (fileSize > 0) { 
      System.out.println("loop"+ i); 
      if (fileSize <= Chunk_Size) { 
       readLength = (int) fileSize; 
      } 
      byteChunk = new byte[(int)readLength]; 
      read = fis.read(byteChunk, 0, (int)readLength); 
      fileSize -= read; 
      // cursor += read; 
      assert(read==byteChunk.length);           
      long aid = fileid; 
      aid = aid<<32 | nChunks;     
      chunks[i] = new DataUnit(byteChunk,aid);     

     // Lister.add(chunks[i]); 
      nChunks++; 
      ++i;      
     } 
     fis.close(); 
     fis = null; 

     }catch(Exception e){ 
      System.out.println("File splitting exception"); 
     e.printStackTrace(); 
    } 

     return chunks;    
    } 
+0

你可以增加你的客戶端程序的堆大小,請看看http://stackoverflow.com/questions/1565388/increase-heap-size-in-java。 – cerkiewny

+0

btw:assert(read == byteChunk.length)可能會觸發。您無法確定讀取的調用會填充陣列 – MTilsted

回答

0

如何創建

byteChunk = new byte[(int)readLength]; 

的循環之外,只是重複使用它,而不是遍地創建一個字節數組,如果它總是相同的。

或者

你可以輸入數據,因爲它來的,而不是堅持認爲巨大的數組,然後處理它,一旦它全部抵達寫入到一個臨時文件。

此外

如果要多次使用它作爲一個int,你應該只是情況讀數長度爲int外循環以及

int len = (int)readLength; 

而且Chunk_Size是一個變量嗎?它應該以小寫字母開頭。

1

隨着文件大小的增加,讀取整個文件肯定會觸發OutOfMemoryError。調整-Xmx1024M可能對臨時修復很有幫助,但絕對不是正確的/可擴展的解決方案。另外,無論你如何移動你的變量(比如在循環外部而不是在循環內創建緩衝區),你遲早都會得到OutOfMemoryError。不要讓OutOfMemoryError爲你的唯一方法是不要讀取內存中的完整文件。

如果你只使用內存,那麼一個辦法是塊歡送到客戶端,這樣你就不必把所有的塊存儲:中

代替:

chunks[i] = new DataUnit(byteChunk,aid); 

做:

sendChunkToClient(new DataUnit(byteChunk, aid)); 

但上述方案的缺點是:如果某些錯誤發生在中間的大塊發送,你可能很難試圖恢復/從錯誤點恢復。

將塊保存到像Ross Drew這樣的臨時文件可能會更好,更可靠。