Java 内存泄漏和runnable类的奇怪错误-如何正确处理对象?
我正在构建一个服务器应用程序,以跟踪有多少人正在运行我最近构建的另一个应用程序。这更多的是为了测试我自己,看看我能用这门语言做些什么,在几乎没有时间的情况下,我就能够让事情顺利进行。然而,在应用程序上运行人工测试时,我遇到了一个严重的问题。我会发布我的代码 主要类别:Java 内存泄漏和runnable类的奇怪错误-如何正确处理对象?,java,multithreading,swing,memory-leaks,runnable,Java,Multithreading,Swing,Memory Leaks,Runnable,我正在构建一个服务器应用程序,以跟踪有多少人正在运行我最近构建的另一个应用程序。这更多的是为了测试我自己,看看我能用这门语言做些什么,在几乎没有时间的情况下,我就能够让事情顺利进行。然而,在应用程序上运行人工测试时,我遇到了一个严重的问题。我会发布我的代码 主要类别: public class ServerGUIStatistics { public static MainWindow mw = null; private static int _port = 33672; public s
public class ServerGUIStatistics {
public static MainWindow mw = null;
private static int _port = 33672;
public static void main(String[] args) {
mw = new MainWindow();
new ServerGUIStatistics();
}
public ServerGUIStatistics(){
ServerSocket listener = null;
try{
listener = new ServerSocket(_port, 100);
while(true){
System.out.println("Waiting for connection....");
Socket connection = listener.accept();
Connection nc = new Connection(connection);
}
}
catch(Exception ex){
mw.setConsoleOutput(ex.getMessage(), 2);// Prints to a console output window...
}
}
我认为引起这些问题的是可燃类
class Connection implements Runnable {
private static int _totalConnections = 0;
private static long _totalConnectionsAllTime = 0;
private Socket socket = null;
private boolean stopFlag = true;
@Override
public void run(){
while(stopFlag){
stopFlag = false;
ServerGUIStatistics.mw.setConsoleOutput("New connection from \"" + socket.getInetAddress().toString() + "\" on port " + socket.getPort(), 0);// Prints to a console output window...
ServerGUIStatistics.mw.updateConNumber(_totalConnections);
ServerGUIStatistics.mw.updateConAllTimeNumber(_totalConnectionsAllTime);//Updates a field on the main window which displays the total number of users connected
boolean stayAlive = true;
try{
socket.setSoTimeout(10000);
BufferedInputStream connectionStatus = new BufferedInputStream(socket.getInputStream());
do{
int holder = connectionStatus.read();
switch(holder){
case 1:
stayAlive = true;
break;
case 0:
stayAlive = false;
break;
}
}
while(stayAlive);
}
catch(IOException ex){
ServerGUIStatistics.mw.setConsoleOutput(socket.getInetAddress().toString() + " " + ex.getMessage(), 2); // Prints to a console output window...
}
_totalConnections--;
ServerGUIStatistics.mw.updateConNumber(_totalConnections); //Updates a field on the main window which displays the current number of users connected
return;
}
}
Connection(Socket soc){
socket = soc;
_totalConnections++;
_totalConnectionsAllTime++;
new Thread(this).start();
}
public static int getTotalConnections(){
return _totalConnections;
}
以下是swing窗口(由netbeans生成):
import java.util.Date;
导入java.text.*;
公共类主窗口扩展了javax.swing.JFrame{
/**
*在主窗口中创建新窗体
*/
私有日期curDate=null;
私有SimpleDataFormat ft=新SimpleDataFormat(“MM/dd/yyyy@hh:MM:ss”);
公共主窗口(){
初始化组件();
此.setVisible(true);
}
/**
*从构造函数中调用此方法来初始化表单。
*警告:不要修改此代码。此方法的内容始终为
*由表单编辑器重新生成。
*/
@抑制警告(“未选中”)
//
私有组件(){
bindingGroup=new org.jdesktop.beansbinding.bindingGroup();
jTabbedPane1=newjavax.swing.JTabbedPane();
jPanel1=newjavax.swing.JPanel();
totalConnectionsOut=newjavax.swing.JTextField();
totalConnectionsAllTimeOut=newjavax.swing.JTextField();
jLabel1=newjavax.swing.JLabel();
jLabel2=newjavax.swing.JLabel();
jPanel3=newjavax.swing.JPanel();
jScrollPane2=newjavax.swing.JScrollPane();
consoleOutput=newjavax.swing.JTextArea();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
totalConnectionsOut.setFont(新的java.awt.Font(“Tahoma”,0,58));//NOI18N
setHorizontalAlignment(javax.swing.JTextField.CENTER);
totalConnectionsOut.setText(“0”);
org.jdesktop.beansbinding.Binding Binding Binding=org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE,totalConnectionsOut,org.jdesktop.beansbinding.ELProperty.create(“false”),totalConnectionsOut,org.jdesktop.beansbinding.BeanProperty.create(“可编辑”);
bindingGroup.addBinding(绑定);
totalConnectionsAllTimeOut.setFont(新的java.awt.Font(“Tahoma”,0,58));//NOI18N
totalConnectionsAllTimeOut.setHorizontalAlignment(javax.swing.JTextField.CENTER);
totalConnectionsAllTimeOut.setText(“0”);
binding=org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE,totalConnectionsAllTimeOut,org.jdesktop.beansbinding.ELProperty.create(“false”),totalConnectionsAllTimeOut,org.jdesktop.beansbinding.BeanProperty.create(“可编辑”);
bindingGroup.addBinding(绑定);
jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
jLabel1.setText(“总连接数:”);
setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
jLabel2.setText(“总电流连接:”);
javax.swing.GroupLayout jPanel1Layout=新的javax.swing.GroupLayout(jPanel1);
setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jpanellayout.createSequentialGroup()
.addContainerGap()
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(总连接输出)
.addComponent(totalConnectionsAllTimeOut,javax.swing.GroupLayout.Alignment.training,javax.swing.GroupLayout.DEFAULT_SIZE,571,Short.MAX_值)
.addComponent(jLabel1,javax.swing.GroupLayout.DEFAULT\u SIZE,javax.swing.GroupLayout.DEFAULT\u SIZE,Short.MAX\u值)
.addComponent(jLabel2,javax.swing.GroupLayout.DEFAULT\u SIZE,javax.swing.GroupLayout.DEFAULT\u SIZE,Short.MAX\u VALUE))
.addContainerGap())
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jpanellayout.createSequentialGroup()
.addComponent(jLabel2,javax.swing.GroupLayout.PREFERRED\u SIZE,29,javax.swing.GroupLayout.PREFERRED\u SIZE)
.addGap(4,4,4)
.addComponent(TotalConnectionOut,javax.swing.GroupLayout.PREFERRED_SIZE,150,javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel1,javax.swing.GroupLayout.DEFAULT\u SIZE,34,Short.MAX\u值)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(totalConnectionsAllTimeOut,javax.swing.GroupLayout.PREFERRED\u大小,150,javax.swing.GroupLayout.PREFERRED\u大小)
.addContainerGap())
);
jTabbedPane1.addTab(“Info”,jPanel1);
控制台输出设置列(20);
控制台输出设置行(5);
binding=org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE,consoleOutput,org.jdesktop.beansbinding.ELProperty.create(“false”),consoleOutput,org.jdesktop.beansbinding.BeanProperty.create(“可编辑”);
bindingGroup.addBinding(绑定);
jScrollPane2.setViewportView(控制台输出);
javax.swing.GroupLayout jPanel3Layout=新的javax.swing.GroupLayout(jPanel3);
setLayout(jPanel3Layout);
jPanel3Layout.setHorizontalGroup(
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel3Layout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane2,javax.swing.GroupLayout.DEFAULT_SIZE,571,Short.MAX_VALUE)
.addContainerGap())
);
jPanel3Layout.setVerticalGroup(
jPanel3Layout.createParallelGroup(javax.swing.GroupLa
import java.util.Date;
import java.text.*;
public class MainWindow extends javax.swing.JFrame {
/**
* Creates new form MainWindow
*/
private Date curDate = null;
private SimpleDateFormat ft = new SimpleDateFormat ("MM/dd/yyyy @ hh:mm:ss");
public MainWindow() {
initComponents();
this.setVisible(true);
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
bindingGroup = new org.jdesktop.beansbinding.BindingGroup();
jTabbedPane1 = new javax.swing.JTabbedPane();
jPanel1 = new javax.swing.JPanel();
totalConnectionsOut = new javax.swing.JTextField();
totalConnectionsAllTimeOut = new javax.swing.JTextField();
jLabel1 = new javax.swing.JLabel();
jLabel2 = new javax.swing.JLabel();
jPanel3 = new javax.swing.JPanel();
jScrollPane2 = new javax.swing.JScrollPane();
consoleOutput = new javax.swing.JTextArea();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
totalConnectionsOut.setFont(new java.awt.Font("Tahoma", 0, 58)); // NOI18N
totalConnectionsOut.setHorizontalAlignment(javax.swing.JTextField.CENTER);
totalConnectionsOut.setText("0");
org.jdesktop.beansbinding.Binding binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, totalConnectionsOut, org.jdesktop.beansbinding.ELProperty.create("false"), totalConnectionsOut, org.jdesktop.beansbinding.BeanProperty.create("editable"));
bindingGroup.addBinding(binding);
totalConnectionsAllTimeOut.setFont(new java.awt.Font("Tahoma", 0, 58)); // NOI18N
totalConnectionsAllTimeOut.setHorizontalAlignment(javax.swing.JTextField.CENTER);
totalConnectionsAllTimeOut.setText("0");
binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, totalConnectionsAllTimeOut, org.jdesktop.beansbinding.ELProperty.create("false"), totalConnectionsAllTimeOut, org.jdesktop.beansbinding.BeanProperty.create("editable"));
bindingGroup.addBinding(binding);
jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
jLabel1.setText("Total Connections:");
jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
jLabel2.setText("Total Current Connections:");
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addContainerGap()
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(totalConnectionsOut)
.addComponent(totalConnectionsAllTimeOut, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 571, Short.MAX_VALUE)
.addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jLabel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap())
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 29, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(4, 4, 4)
.addComponent(totalConnectionsOut, javax.swing.GroupLayout.PREFERRED_SIZE, 150, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, 34, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(totalConnectionsAllTimeOut, javax.swing.GroupLayout.PREFERRED_SIZE, 150, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
);
jTabbedPane1.addTab("Info", jPanel1);
consoleOutput.setColumns(20);
consoleOutput.setRows(5);
binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, consoleOutput, org.jdesktop.beansbinding.ELProperty.create("false"), consoleOutput, org.jdesktop.beansbinding.BeanProperty.create("editable"));
bindingGroup.addBinding(binding);
jScrollPane2.setViewportView(consoleOutput);
javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
jPanel3.setLayout(jPanel3Layout);
jPanel3Layout.setHorizontalGroup(
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel3Layout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 571, Short.MAX_VALUE)
.addContainerGap())
);
jPanel3Layout.setVerticalGroup(
jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel3Layout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 368, Short.MAX_VALUE)
.addContainerGap())
);
jTabbedPane1.addTab("Console Output", jPanel3);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jTabbedPane1)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jTabbedPane1)
);
bindingGroup.bind();
pack();
}// </editor-fold>
public void setConsoleOutput(String s, int i){
String type = null;
switch(i){
case 0:
type = "Info";
break;
case 1:
type = "Error";
break;
case 2:
type = "Exception";
break;
default:
type = "Unknown";
break;
}
curDate = new Date();
String output = consoleOutput.getText() + "[" + ft.format(curDate) + "][" + type + "] " + s + "\n";
consoleOutput.setText(output);
}
public void updateConNumber(int i){
totalConnectionsOut.setText(Integer.toString(i));
}
public void updateConAllTimeNumber(long i){
totalConnectionsAllTimeOut.setText(Long.toString(i));
}
// Variables declaration - do not modify
private javax.swing.JTextArea consoleOutput;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel3;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JTabbedPane jTabbedPane1;
private javax.swing.JTextField totalConnectionsAllTimeOut;
private javax.swing.JTextField totalConnectionsOut;
private org.jdesktop.beansbinding.BindingGroup bindingGroup;
// End of variables declaration
class Main{
public static void main(String[] args){
while(true){
try{
Socket socket = new Socket("127.0.0.1", 33672);
BufferedOutputStream out = new BufferedOutputStream(socket.getOutputStream());
for(int i = 0; i < 5; i++){
out.write(1);
out.flush();
Thread.sleep(10);
}
out.write(0);
out.flush();
out.close();
socket.close();
}
catch(Exception ex){System.out.println(ex);}
System.out.println("Finished! Running again...");
}
}
}
while(stopFlag){
stopFlag = false;
ServerGUIStatistics.mw.setConsoleOutput("New connection from \"" + socket.getInetAddress().toString() + "\" on port " + socket.getPort(), 0);// Prints to a console output window...
ServerGUIStatistics.mw.updateConNumber(_totalConnections);
ServerGUIStatistics.mw.updateConAllTimeNumber(_totalConnectionsAllTime);//Updates a field on the main window which displays the total number of users connected
boolean stayAlive = true;
try{
socket.setSoTimeout(10000);
BufferedInputStream connectionStatus = new BufferedInputStream(socket.getInputStream());
do{
int holder = connectionStatus.read();
switch(holder){
case 1:
stayAlive = true;
break;
case 0:
stayAlive = false;
break;
}
}
while(stayAlive);
}
catch(IOException ex){
ServerGUIStatistics.mw.setConsoleOutput(socket.getInetAddress().toString() + " " + ex.getMessage(), 2); // Prints to a console output window...
}
_totalConnections--;
ServerGUIStatistics.mw.updateConNumber(_totalConnections); //Updates a field on the main window which displays the current number of users connected
return;
}
ServerGUIStatistics.mw.setConsoleOutput("New connection from \"" + socket.getInetAddress().toString() + "\" on port " + socket.getPort(), 0);// Prints to a console output window...
ServerGUIStatistics.mw.updateConNumber(_totalConnections);
ServerGUIStatistics.mw.updateConAllTimeNumber(_totalConnectionsAllTime);//Updates a field on the main window which displays the total number of users connected
boolean stayAlive = true;
try {
socket.setSoTimeout(10000);
try (BufferedInputStream connectionStatus = new BufferedInputStream(socket.getInputStream())) {
do {
System.out.println(number + " reading...");
int holder = connectionStatus.read();
System.out.println(number + " read " + holder + "...");
switch (holder) {
case 1:
stayAlive = true;
break;
case 0:
stayAlive = false;
break;
}
} while (stayAlive);
}
} catch (IOException ex) {
ServerGUIStatistics.mw.setConsoleOutput(socket.getInetAddress().toString() + " " + ex.getMessage(), 2); // Prints to a console output window...
} finally {
System.out.println(number + " exiting");
_totalConnections--;
try {
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
socket = null;
ServerGUIStatistics.mw.updateConNumber(_totalConnections); //Updates a field on the main window which displays the current number of users connected
}
public void setConsoleOutput(String s, int i){
String type = null;
switch(i){
case 0:
type = "Info";
break;
case 1:
type = "Error";
break;
case 2:
type = "Exception";
break;
default:
type = "Unknown";
break;
}
curDate = new Date();
String output = consoleOutput.getText() + "[" + ft.format(curDate) + "][" + type + "] " + s + "\n";
consoleOutput.setText(output);
}
String output = consoleOutput.getText() + "[" + ft.format(curDate) + "][" + type + "] " + s + "\n";
public void setConsoleOutput(String s, int i) {
String type = null;
switch (i) {
case 0:
type = "Info";
break;
case 1:
type = "Error";
break;
case 2:
type = "Exception";
break;
default:
type = "Unknown";
break;
}
String output = "[" + ft.format(System.currentTimeMillis()) + "][" + type + "] " + s + "\n";
consoleOutput.append(output);
}