gpt4 book ai didi

java - java应用程序中无限循环的内存不足和stackoverflow异常

转载 作者:行者123 更新时间:2023-12-02 07:38:18 25 4
gpt4 key购买 nike

我有一个简单的应用程序,用于监听 UDP 消息。该应用程序需要无限期运行。它通过实例化我创建的 MySQLConnect 对象来实例化单个 jdbc 数据库连接它看起来像这样:

 public MySQLConnect() {
this.instantiateConnection();
}

//Open the database connection. Done iniitally in
//the main class and only called again if the connection
//is closed due to an error in processing a message
public Connection instantiateConnection() {

try {

Class.forName("com.mysql.jdbc.Driver");

connection = DriverManager
.getConnection("jdbc:mysql://localhost:3306/mydb?"
+ "user=user&password=pwd");
} catch (Exception e) {
e.printStackTrace();
}

return connection;
}

一旦应用程序启动,就会从 UDPReceiver 类调用 MySQLConnect 类构造函数。只有在处理错误并且数据库连接关闭时才会再次调用它。这个类看起来像:

 public class UDPReceiver {

private static int port = 2140;
private static int byteSize = 1024;
private static int timeOut = 5000;
@SuppressWarnings("unused")
private static int count;
static MySQLConnect dbConnect;


public static void main(String[] args) {

recvUDPMessage();
}

public static String recvUDPMessage() {
DataTransferService dts = new DataTransferServiceImp();
dbConnect = new MySQLConnect();

try {

DatagramSocket dsocket = null;
if (dsocket == null) {
dsocket = new DatagramSocket(port);
dsocket.setBroadcast(true);
dsocket.setReuseAddress(false);
}
byte[] inbuf = new byte[byteSize];
byte[] rcvMsg;
InetAddress fromIP;

DatagramPacket receivepacket = new DatagramPacket(inbuf,
inbuf.length);
dsocket.setSoTimeout(timeOut);

//Infinitely loop and listen for UDP messages

count = 0;
boolean loopRecv = true;
while (loopRecv) {
try {
count++;
dsocket.receive(receivepacket);
// temp = receivepacket.getAddress().toString();
fromIP = receivepacket.getAddress();
String fromIPString = fromIP.toString();
rcvMsg = receivepacket.getData();
String rcvString = new String(rcvMsg, 0, rcvMsg.length);
String rcvMessage = "Message Received from: "
+ fromIPString + " Message: " + rcvString + "\n";
System.out.println(rcvMessage);



ArrayList<String> al = getMessageElements(rcvString);



//Send array of message elements to service layer
dts.saveUDPMessage(dbConnect, al, Utils.getTimeStamp());

loopRecv = true;
} catch (IOException e) {
System.out.println("Listening . . .");



loopRecv = true;
}
}
} catch (SocketException e) {
System.err.println("Sockets Exception: " + e.getMessage());
} catch (Exception e) {
System.err.println(" Exception: " + e.getMessage());

} finally {
System.out.println(". . . Close DB");
dts.closeDBConnection(dbConnect);


// I added the creation MySQLConnect object after I was getting an error that the database was closed when trying to insert.
dbConnect = new MySQLConnect();
}
return "end of routine";
}

//Extract comma delimited message elements into an array
private static ArrayList<String> getMessageElements(String rcvString) {
StringTokenizer st = new StringTokenizer(rcvString, ",");

ArrayList<String> al = new ArrayList<String>();

while (st.hasMoreElements()) {
String messageElement = (String) st.nextElement();
al.add(messageElement);

}



return al;
}

}

这运行了大约 8 小时,然后我收到以下错误:

主线程 java.lang.stackoverflowerror 中出现异常

异常:从主线程中的 uncaughtExceptionhandler 抛出 java.lang.outofmemoryerror

以前,我在数据库关闭后没有重新实例化 MySQLConnect 对象。问题是我收到数据库连接已关闭的错误,但我的程序仍在尝试执行 jdbc 插入。 jdbc insert 首先检查是否有实例化的连接,如果没有则实例化它。 MySQLConnect 类中的这段代码如下所示:

 PreparedStatement prep = null;

if (connection == null) {
connection = this.instantiateConnection();
}

try {

prep = connection
.prepareStatement("insert into MyTable (UDPMessage)"
+ "values (?);");

prep.setString(1, udpMessage);




prep.addBatch();

prep.executeBatch();

如何构建此流程以正确处理无限期传入的 UDP 消息并写入数据库,即使发生错误也是如此?

另外,当处理数据出现异常时,如何解决重新实例化 MySQLConnect 类时出现内存不足错误的问题?

如果异常后实例化该类不正确,如何重新实例化与数据库的连接以继续处理数据?

感谢您的帮助!

最佳答案

您没有在代码中的任何位置将 boolean 值 loopRecv 设置为 false,这会导致无限循环(而条件始终解析为 true )。无限/递归循环保留在填充堆栈上,但不会删除任何堆栈帧并导致 StackOVerflowError

关于java - java应用程序中无限循环的内存不足和stackoverflow异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11906819/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com