簡體   English   中英

釋放Java中未使用的RAM

[英]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。

現在,對於“釋放完成的文件及其數據”部分,您不能真正自己做,也不應嘗試這樣做。

  • 如果希望您的應用程序具有更高的內存效率,則只需將最大堆大小設置為一個較小的值。
  • 另一方面,如果您希望應用程序真的非常快,那么您就不會遭受任何GC的困擾,因此消除了每個System.gc()調用,並為您的堆提供了盡可能多的內存。

嘗試自己釋放內存意味着給堆增加過多的內存(您的應用程序不節省內存)並自己觸發GC(您的應用程序也不節省時間)。

請注意,在某些情況下,JVM可以將內存還給操作系統。 例如,使用G1,它將,但是使用CMS,它將不會。 有關更多詳細信息,請參見本文

最后,如果使用Java7,則應將您的InputStream / OutputStream包裝在try-with-resources中。 或者,至少將.close()包裝在finally塊中。

希望有幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM