【发布时间】:2015-03-29 10:50:46
【问题描述】:
我在 jvm 释放内存时遇到了问题。我知道java在退出run方法后释放线程资源的内存。当其他对象没有引用时,垃圾收集器会删除其他对象,但有一些例外,如窗口/框架。为什么在下面的代码中,尽管线程结束了工作,但 gc 不释放字节数组的内存?我知道 System.gc() 只是对 gc 的建议,但我使用它以防万一,为字节数组引用分配 null 是不必要的。
下面的代码只是示例,当服务器向客户端发送文件时,我的客户端-服务器应用程序在类似情况下遇到了真正的问题。
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
int j=0;
for (int i=0;i<5;i++){
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
}
j++;
new Thread(new Runnable(){
public void run(){
byte[] bytes=new byte[1024*1024*100];
try {
Thread.sleep(15000);
} catch (InterruptedException ex) {
Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("exiting "+Thread.currentThread().getName());
bytes=null;
System.gc();
}
}, ""+j).start();
}
System.gc();
}
我离开上面的问题,去实用。早些时候,将整个文件加载到一个字节数组并使用 writeObject() 发送它,但这会导致内存问题。看看那个代码:
BufferedOutputStream bos = null;
byte[] bytes;
int count;
for (int i = 0; i < filesToUpdate.size(); i++) {
if (mapp.get(filesToUpdate.get(i)) == null) {
addNewFile(filesToUpdate.get(i));
}
bos = new BufferedOutputStream(new FileOutputStream(new File(filesToUpdate.get(i))));
long bufferSize = ois.readLong();
ous.writeObject(2);
ous.flush();
bytes =new byte[8192];
while ((count=ois.read(bytes))>0){
bos.write(bytes, 0, count);
}
bos.flush();
bos.close();
ous.writeObject(3);
ous.flush();
}
ois.readObject();
updateRevision(mapp, filesToUpdate);
接收文件的是客户端。在收到最后一个数据包后,第一个文件中的读取方法块。 这是服务器端:
int count;
File file;
FileInputStream fis=null;
byte[] bytes;
for (int i=0;i<filesForPatch.size();i++){
if (pc.getWhat()==0)
path="admin/";
else path="client/";
path+=filesForPatch.get(i);
file=new File(path);
long buffSize=file.length();
ous.writeLong(buffSize);
ous.flush();
ois.readObject();
fis=new FileInputStream(file);
bytes=new byte[8192];
while ((count=fis.read(bytes))>0){
ous.write(bytes, 0, count);
}
ous.flush();
fis.close();
ois.readObject();
}
任何想法如何解决这个问题?
【问题讨论】:
-
如何检查 Java 没有释放字节数组的内存?基本上,你能发布一些东西来支持你的主张吗??
-
我通过windows任务管理器查看。
-
您能否详细说明 Windows 任务管理器的哪些统计信息让您相信导致内存泄漏的是字节数组,而不是程序的其他部分,或者您的其他应用程序整个系统?
-
这是一个非常简单的程序,只有上面的代码和带有按钮创建的框架。那么还有什么可以解决内存泄漏呢?
-
没错。所以 Windows 任务管理器不会告诉你它是字节数组。你觉得是字节数组是罪魁祸首吧?为什么感觉字节数组是罪魁祸首?
标签: java memory garbage-collection jvm