[英]infinite while loop gives java.lang.OutOfMemoryError: Java heap space
[英]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秒。
我的一些觀察:
有兩個問題。
(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.