2014-10-10 31 views
0

我正在編寫客戶端服務器程序。客戶端位於同一WLAN上的另一臺計算機上。我面臨的問題是客戶端的這種例外情況:java.lang.OutOfMemoryError: Java heap space如何解決OutOfMemory:我的客戶端程序上的Java堆空間(使用Eclipse)

問題是,如果我也使用服務器計算機作爲客戶端(同一臺計算機上的Server-Client),它不會拋出此異常。但是,每次我從另一臺計算機運行客戶端以下載文檔時,都會引發異常。

請幫助一個簡單的方法來解決這個問題。我使用Eclipse。

下面是我的客戶端類:

public void run() { 
    try { 
      servsock = new ServerSocket(13330); 

     while (true) { 
      System.out.println("Waiting on question server..."); 
      try { 
      sock = servsock.accept(); 
      System.out.println("Accepted connection : " + sock); 
      // receive file 
      byte [] mybytearray = new byte [FILE_SIZE]; 
      InputStream is = sock.getInputStream(); 
      String LocalLocation = "C:\\NewEvalve\\LocalUploadedFiles\\"+clasx+"\\"+subject+"\\"+filename; 
      File LocalFile = new File(LocalLocation); 

      File file = new File("C:\\NewEvalve\\LocalUploadedFiles\\"+clasx+"\\"+subject); 
      if (!file.exists()) { 
       new File("C:\\NewEvalve\\LocalUploadedFiles\\"+clasx+"\\"+subject).mkdirs(); 
       System.out.println(file+ " now exists."); 
       } 
      File outputfile = new File("C:\\NewEvalve\\LocalUploadedFiles\\"+clasx+"\\"+subject+"\\"+filename); 
      fos = new FileOutputStream(outputfile); 
      bos = new BufferedOutputStream(fos); 
      bytesRead = is.read(mybytearray,0,mybytearray.length); 
      current = bytesRead; 

      do { 
      bytesRead = 
       is.read(mybytearray, current, (mybytearray.length-current)); 
      if(bytesRead >= 0) current += bytesRead; 
      } while(bytesRead > -1); 

      bos.write(mybytearray, 0 , current); 
      bos.flush(); 
      System.out.println("File " + FILE_TO_RECEIVED 
       + " downloaded (" + current + " bytes read)"); 
     } 
     finally { 
      if (fos != null) fos.close(); 
      if (bos != null) bos.close(); 
      if (sock != null) sock.close(); 
     } } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

......這裏是我的服務器類上傳文件:

public void uploadIt(InetAddress retur2, String fileLocation2){ 
    try{ 
    File myFile = new File (fileLocation2); 
    sock = new Socket(retur2, 13330); 
    System.out.println("Connection on "+sock.getRemoteSocketAddress()); 
    os = sock.getOutputStream(); 
    byte [] mybytearray = new byte [(int)myFile.length()]; 
    fis = new FileInputStream(myFile); 
    bis = new BufferedInputStream(fis); 
    bis.read(mybytearray,0,mybytearray.length); 
    os.write(mybytearray,0,mybytearray.length); 
    fis.close(); 
    bis.close(); 
    os.flush(); 
    os.close(); 
    System.out.println("Sent " + fileLocation2 + "(" + mybytearray.length + " bytes)"); 
    } catch (UnknownHostException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    finally { 
    try { 
     if (bis != null)bis.close(); 
    if (os != null) os.close(); 
    if (sock!=null) sock.close(); 
    System.out.println("Completed Upload"); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     }} 

} 
+0

你'FIS,二,操作系統,FOS,bos'收盤看起來並不健康。你首先應該送一些時間乾淨的一團糟。 – Serhiy 2014-10-10 12:10:05

+0

你正在閱讀哪種類型的文件(二進制,文本等)? – OO7 2014-10-10 12:30:00

+0

我正在閱讀短視頻,音頻和基於文本的文件 - 最多不能超過100MB(最差)。我需要關於如何以小塊讀取文件的幫助_任何人都可以請幫助一個示例代碼? – Jojo 2014-10-10 13:39:53

回答

1

如果你是閱讀文本文件那麼你應該使用的BufferedReader &的BufferedWriter,而不是一次讀取整個文件,這樣

File file = new File("your file"); 
FileWriter fw = new FileWriter(file.getAbsoluteFile()); 
BufferedWriter bw = new BufferedWriter(fw); 
BufferedReader br = new BufferedReader(new FileReader("your file")); 
while ((currentLine = br.readLine()) != null) { 
    bw.write(currentLine); 
} 
bw.close(); 
br.close(); 

如果你是讀取二進制文件那麼建議使用BufferedInputStream & BufferedOutputStream。您無法使用BufferedReader讀取二進制數據,因爲它將二進制數據轉換爲字符串格式&您的文件將被破壞或損壞。

這可能是有可能在您的文件中沒有行終止符。在這種情況下,閱讀器將繼續讀取文件,直到堆內存空間爲止。這就是爲什麼你會得到OutOfMemory錯誤。


編輯:

執行讀取音頻文件存在Java標準版可擴展/寫操作 - 聲音。您可以使用javax.sound.sampled。*包中的類。

舉例音頻文件:

File fileIn = new File("your file"); 
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(fileIn); 
// do something 
File fileOut = new File("new file"); 
if (AudioSystem.isFileTypeSupported(AudioFileFormat.Type.WAVE, audioInputStream)) { 
    AudioSystem.write(audioInputStream, AudioFileFormat.Type.WAVE, fileOut); 
} 

要在這個Java Sound API


得到音響包看看詳細的主意,用你能做到像下面視頻文件格式工作: -

Java getResourceAsStream("your video file")中有方法返回InputStream的一個對象。您可以使用此流來讀取視頻文件數據&將其寫入另一個文件或任何您想要執行的操作。

InputStream getResourceAsStream(String name) - Java Doc一些示例代碼如下所示: -

try { 
    InputStream in = this.getClass().getResourceAsStream("your video file"); 
    BufferedInputStream bis = new BufferedInputStream(in); 
    BufferedOutputStream bus = new BufferedOutputStream(new FileOutputStream(
             new File("your new video file"))); 
    byte[] data = new byte[in.available()]; 
    int read = in.read(data); 
    bus.write(read); 
} catch (IOException ex) { 
} 
+0

有一點!我正在使用代碼來閱讀視頻,音頻,文本文件等...這可能意味着我應該分別讀取每種類型的文件。我同意,我也應該讀一點點...... – Jojo 2014-10-10 13:34:31

+0

如果這個答案可以幫助你解決你的錯誤,那麼你應該接受它。 – OO7 2014-10-10 13:38:17

+0

什麼是最好的方式來閱讀音頻和視頻文件?我可以使用什麼形式的讀寫流? – Jojo 2014-10-10 13:53:34

-1

儘量擡高燙髮空間,添加以下參數到VM啓動

-XX:PermSize =256米-XX:MaxPermSize參數=256米

還添加-XX:MaxPermSize參數=256米to Tomcat in Eclipse: Server > Open Launch Configuration > Arguments

參考鏈接是在這裏:Out of memory

0

實際上你可以調整你的虛擬機將使用的最大內存量。只需使用-Xmx<size>參數來調整。例如-Xmx512m將使用最多512 MB的內存。

我也注意到你正在讀取一個文件作爲大塊進入內存。爲了防止巨大的即時內存需求,我會一塊一塊地做(如1或2 kb的塊)。

0

根據機器上的物理內存總量,HotSpot根據其大小調整堆大小。當您更改主機時,您會隱式更改堆棧限制。看起來,在你的遠程機器上,你的RAM很少,所以你達到了極限。

但是,真正的建議並不是將整個文件加載到內存中;而是以塊的形式讀取文件,並將它們直接寫入網絡套接字。那麼無論文件大小如何,您都不會面臨這個問題。同樣的推理也適用於服務器端:不要將整個文件從套接字讀取到RAM中,而是直接將其轉儲到文件中。

+0

是的,我真的不知道如何去閱讀大塊文件,我正在上傳,短片,音頻,基於文本的文件,你能幫我一個這樣做嗎?謝謝 – Jojo 2014-10-10 13:36:55

相關問題