簡體   English   中英

無限循環導致OutOfMemoryError:Java堆空間

[英]Infinite loop causes OutOfMemoryError: Java heap space

我正在編寫一個聊天應用程序。 我使用while(true)無限循環來允許應用程序不斷“監聽”通過控制台的用戶輸入和來自Socket輸入。 無限循環顯然不是實現此目的的最佳方法-毫不奇怪,僅在程序運行約一分鍾后(我的計算機迷就尖叫),我得到了OutOfMemoryError: Java Heap space

我的問題是:如果不通過無限循環,如何修改程序以不斷(或至少每隔很小的時間間隔,如每秒一次)檢查輸入源,做出響應,然后返回檢查?

代碼(帶有一些注釋)如下:

import java.io.*;
import java.net.*;

public class Main {
    public static void main(String[] args) throws IOException, ConnectException {
        ServerSocket receiveServerSocket = new ServerSocket(Integer.parseInt(args[0])); // args contains two port numbers
        Socket sendSocket;
        while(true) { // note - I use the exact same infinite loop strategy here, except in this case an OutOfMemoryError is not thrown
            try {
                sendSocket = new Socket(InetAddress.getLocalHost(), Integer.parseInt(args[1]));
                break;
            } catch (ConnectException e) {}
        }
        DataOutputStream os = new DataOutputStream(sendSocket.getOutputStream());
        Socket receiveSocket = receiveServerSocket.accept();
        DataInputStream is = new DataInputStream(receiveSocket.getInputStream());
        BufferedReader input = new BufferedReader (new InputStreamReader(System.in));
        String message;
        while(true) { // Here's the infinite loop in question
            if(input.ready()) { // "checks" to see if the user has entered text
                message = input.readLine(); // responds
                os.writeInt(message.getBytes().length);     
                os.writeBytes(message);
            }
            if(is.available() > 0) { // checks to see if Socket has received text
                byte[] bytes = new byte[is.readInt()]; // responds (Incidentally, this is the specific line where the OutOfMemoryError occurs)
                is.read(bytes,0,bytes.length);
                System.out.println(new String(bytes,0,bytes.length,"UTF-8"));
            }
        }
    }
}

謝謝

嘗試打印is.readInt()的值。 您可能正在讀取垃圾值並試圖分配那么多內存,從而導致OutOfMemoryError。 另外,將while循環放入線程中,並調用Thread.sleep(1000)使檢查周期為1秒。

我的一些觀察:

  • 您的第一個循環不是無限循環。
  • 您可能想使用Thread.slpee(1000)在兩次讀取之間睡眠
  • 完成后釋放字節​​數組。 字節=空; //第二個if語句中的最后一個語句

有兩個問題。

(1)您需要更改

os.writeBytes(message);

os.write(message.getBytes(), 0, message.getBytes().length);

原因是writeBytes從每個String丟棄一個字節。 從Javadoc-

將字符串作為字節序列寫出到基礎輸出流中。 字符串中的每個字符通過丟棄高八位來依次寫出。 如果未引發異常,則寫入的計數器將增加s的長度。

當然,這樣做的效果是,寫入的字節數實際上是調用writeInt時指定的字節數的一半。

(2)如果字節序列以數字字符開頭,則應在調用writeInt之后寫一些分隔符,例如空格。 否則,對readInt的調用可能會從流中讀取錯誤的數字。

您的第一個while循環實際上不是一個循環,因為它在為sendsocket分配了值后立即中斷了。

也許有一個標志為您的應用程序像

bool isRunning=true;

你可以做

while(isRunning) 

當您的應用程序關閉時,它將更改isRunning = false,並退出循環。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM