[英]Java does not free memory
我有一個守護程序,該程序讀取文件的內容,然后將其壓縮並將其寫入較小的.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);
}
你太過分了。 所有的null設置和gc()
調用實際上都沒有幫助,並且刷新和關閉的次數是您實際需要的幾倍。 另外,您根本不需要使用讀取器和寫入器。 所有可以簡化為:
GZIPOutputStream gzipos = null;
while (true)
{
if (f.length() != 0)
{
if (outputfile == null)
{
outputfile = outputfileroot + "_" + outputPart + ".tar.gz";
gzipos = new GZIPOutputStream(new FileOutputStream(outputfile));
}
else
{
if (new File(outputfile).length() > maxLengthOutputFile)
{
gzipos.close();
System.out.println("Finished writing " + outputfileroot + "_" + outputPart + ".tar.gz");
outputfile = outputfileroot + "_" + ++outputPart + ".tar.gz";
gzipos = new GZIPOutputStream(new FileOutputStream(outputfile));
}
}
/**
* Read the entire file
*/
InputStream in = new FileInputStream(f);
byte[] buffer = new byte[8192];
int count;
while ((count = in.read(buffer)) > 0)
{
gzipos.write(buffer, 0, count);
}
in.close();
gzipos.flush();
/**
* Empty it
*/
f.createNewFile();
}
Thread.sleep(1000);
}
我對您的評論沒有任何意義,“會將內容發送到另一個線程,所以我需要逐行閱讀”。 此代碼中沒有線程,您不需要逐行輸入。
我也很好奇它如何與生成輸入文件的內容進行交互。 我認為您應該重命名輸入文件,並在決定復制它時立即在其位置創建一個新的空文件,而不是在復制步驟之后。
System.gc()
發送垃圾回收請求。 運行時決定是執行它還是忽略所述請求。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.