[英]Free unused RAM in Java
我有一個Java類,可分配目錄(6GB)中的所有文件。 然后對每個文件進行一些文本處理。 當我檢查ram的用法時,我可以看到當我從一個文件結束並開始到下一個文件時,RAM不會擺脫前一個文件-我猜是垃圾回收不好。 有沒有辦法以編程方式釋放完成的文件及其數據?
public void fromDirectory(String path) {
File folder = new File(path);
disFile = path + "/dis.txt";
if (folder.isDirectory()) {
File[] listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++) {
File file = listOfFiles[i];
if (file.isFile() && file.getName().contains("log")) {
System.out.println("The file will be processed is: "
+ file.getPath());
forEachFile(file.getPath());
//Runtime.getRuntime().exec("purge");
//System.gc();
} else
System.out.println("The file " + file.getName()
+ " doesn't contain log");
}
} else {
System.out.println("The path: " + path + " is not a directory");
}
}
private void forEachFile(String filePath) {
File in = new File(filePath);
File out = new File(disFile);
try {
out.createNewFile();
FileWriter fw = new FileWriter(out.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
BufferedReader reader = new BufferedReader(new FileReader(in));
String line = null;
while ((line = reader.readLine()) != null) {
if (line.toLowerCase().contains("keyword")) {
bw.write(line);
bw.newLine();
numberOfLines++;
}
}
reader.close();
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
您可以強烈建議VM通過調用System.gc()
進行垃圾回收。 通常認為是這樣做的代碼氣味。
我認為您在這里弄錯了兩件事:JVM的內存分配和分配空間中的實際內存使用情況。
JVM可能會分配大量內存,即使正在使用內存的對象在內部進行了垃圾處理,也無法釋放內存。 可能會在一段時間后釋放它,或者根本不釋放它。
您可以嘗試減少應用程序的內存占用,例如不使用toLowerCase,因為它創建了一個新對象。 也許預編譯的正則表達式搜索會更快?
在我看來,按您的方式使用System.gc()
是可以接受的。 它是否有幫助-我不知道。
只要您有大量可用內存,並且Java不會由於無法分配更多內存而減慢速度,我將保持原樣。 代碼看起來不錯。
即使您正確地從某些探查器檢查內存並“正確”推斷出該文件仍在內存中,您為什么認為應該立即釋放它呢?
當內存用完時(取決於JVM配置),而不是在開發人員認為應該使用時,JVM會進行垃圾回收。
同樣從您的問題來看,我懷疑您是否使用了探查器或類似的工具來衡量JVM內存使用情況。 相反,您更有可能檢查了整個JVM所使用的內存。
另外,除非遇到內存不足的錯誤,否則您不必擔心這些事情。
如前所述,當沒有更多可用內存時,垃圾收集器就會運行。 如果您有10
文件,每個文件大小為100MB
,並且將堆設置為4GB
,那么很可能根本就不會獲得任何GC。
現在,對於“釋放完成的文件及其數據”部分,您不能真正自己做,也不應嘗試這樣做。
System.gc()
調用,並為您的堆提供了盡可能多的內存。 嘗試自己釋放內存意味着給堆增加過多的內存(您的應用程序不節省內存)並自己觸發GC(您的應用程序也不節省時間)。
請注意,在某些情況下,JVM可以將內存還給操作系統。 例如,使用G1,它將,但是使用CMS,它將不會。 有關更多詳細信息,請參見本文 。
最后,如果使用Java7,則應將您的InputStream
/ OutputStream
包裝在try-with-resources中。 或者,至少將.close()
包裝在finally塊中。
希望有幫助!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.