0

ドライブを再帰的にトラバースして、いくつかのファイルを検索しようとしています。フォルダ/ファイルが限られている場合、コードは正常に機能しますが、ファイルがたくさんあるCドライブを検索対象にすると、ヒープメモリが不足します。

スレッド「Thread-4」の例外java.lang.OutOfMemoryError:Javaヒープスペース

  1. 特に再帰呼び出しを行う場合は、メモリ管理の優れたトリックをいくつか提案してください。
  2. または、再帰せずにディレクトリをトラバースするためのより良いアプローチを教えてください。

そして、問題を当面延期するのと同じように、最大​​許容ヒープスペースを増やしたくありません。

コード:

void iterateDirectory(String somedir) {


        File dir = new File(somedir);
        File[] files = dir.listFiles();
        if (files != null) {
            for (int id = 0; id < files.length; id++) {
                if (files[id].isDirectory() == false) 
                {
                   fsTree.add(files[id].toString()); // taking list of files
                } 
                else 
                {
                    iterateFilesInDirectory(files[id].getAbsolutePath());
                }
            }
        }
    }
4

3 に答える 3

2

私が見るように、犯人はこの行です:

fsTree.add(files[id].toString()); // taking list of files

すべてのファイルをグローバルデータ構造( )に追加しfsTree、そこで検索しているようです。

私の賭けは:

A.再帰関数を反復関数に「変換」しても消えることはありません。

B.グローバルデータ構造追加して最終的に検索する代わりに、ローカルで検索/マッチングを実行し、一致するヒットのみをグローバルにキャッシュすると、それはなくなります。

void iterateDirectory (String somedir, String search_term) {

    File dir = new File(somedir);
    File[] files = dir.listFiles();
    if (files != null) {
        for (int id = 0; id < files.length; id++) {
            if (files[id].isDirectory() == false) 
            {
               if (/* files[id].isDirectory() MATCHES search_term */)
                 // add to list of matching files:
                 matching_hits.add(files[id].toString());
            } 
            else 
            {
                iterateFilesInDirectory(files[id].getAbsolutePath());
            }
        }
    }
}
于 2012-05-18T15:37:44.247 に答える
1

2つの可能性があります:

  1. コードには無限の再帰があります(たとえば、処理.していないか、..正しくないため)。その場合は、コードを修正する必要があります。
  2. あなたのコードは本当に利用可能なものよりも多くのヒープスペースを必要とします。2つのオプションがあります。
    • プロセスのメモリ要件を削減します(メモリプロファイラーは、すべてのヒープスペースを使用しているものを理解するのに役立ちます)。
    • -XmxJVMオプションを指定して、ヒープサイズを増やします。
于 2012-05-18T15:03:25.273 に答える
-1

再帰で実行できること、つまりスタック/ヒープの使用に関しては制限があります。再帰的に実行できることは何でも、反復的に実行できることを忘れないでください。代わりに反復ソリューションを使用するようにコードを書き直してください。

代替ソリューション:java.nioファイルシステムの構造を再帰的にウォークダウンするために使用できるインターフェースがあります。このトレイルを見てください、そしてSimpleFileVisitor

于 2012-05-18T15:01:40.363 に答える