【发布时间】:2013-02-19 17:23:15
【问题描述】:
我有一个守护程序,它读取文件的内容,然后将其压缩并写入更小的 .tar.gz 文件。
出于某种原因,Java 继续分配内存,即使在我释放(或者我认为我已经)所有使用的内存之后。我的代码/推理有什么问题?
FileOutputStream fos = null;
GZIPOutputStream gzipos = null;
OutputStreamWriter osw = null;
BufferedWriter bw = null;
while (true) {
if (f.length() != 0) {
if (outputfile == null) {
outputfile = outputfileroot + "_" + outputPart + ".tar.gz";
fos = new FileOutputStream(outputfile);
gzipos = new GZIPOutputStream(fos);
osw = new OutputStreamWriter(gzipos);
bw = new BufferedWriter(osw);
}
else if (new File(outputfile).length() > maxLengthOutputFile) {
bw.flush();
osw.flush();
gzipos.flush();
fos.flush();
bw.close();
osw.close();
gzipos.close();
fos.close();
bw = null;
osw = null;
gzipos = null;
fos = null;
System.gc();
System.out.println("Finished writing " + outputfileroot + "_" + outputPart + ".tar.gz");
outputfile = outputfileroot + "_" + ++outputPart + ".tar.gz";
fos = new FileOutputStream(outputfile);
gzipos = new GZIPOutputStream(fos);
osw = new OutputStreamWriter(gzipos);
bw = new BufferedWriter(osw);
}
/**
* Read the entire file
*/
BufferedReader br = new BufferedReader(new FileReader(f));
String line;
while ((line = br.readLine()) != null) {
// will send the content to another thread, so I need to read it line by line
bw.write(line + "\r\n");
}
br.close();
br = null;
bw.flush();
/**
* Empty it
*/
FileWriter fw = new FileWriter(f);
fw.write("");
fw.flush();
fw.close();
fw = null;
}
Thread.sleep(1000);
}
【问题讨论】:
-
我发现的一件事是,你永远不会结束 while 循环,即 while(true)
-
顺便说一句,如果未使用,java 不会立即删除内存。由 VM 来释放内存
-
你怎么知道它一直在分配内存?您是否遇到内存不足错误?代码中的 System.gc() 不需要真正做 任何事情; JVM 可以将其解释为仅仅是一个提示。
-
使用 jvisualvm(或其他分析器)分析内存分配并找到它分配未释放内存的位置。
-
@cIph3r - 大概所有东西都包装在一个抛出异常或类似东西的方法中; Thread.sleep() 应该避免过多的 CPU 使用。