2017-02-10 13 views
1

私は素晴らしいソフトウェアをC#で構築しています。対象バージョン:.net 4.5。コア仕事の1つは、ファイルのリスト(ルートフォルダー内のさまざまなディレクトリーおよびサブディレクトリーに含まれています)を作成してから、その時に1つを圧縮します。.net 4.5 ZipArchive - 私のソフトウェアやライブラリのメモリリーク?

私は、ZipArchiveクラスを内部で使用していますSystem.IO.Compression;

ここでは、コードです:

// STEP 1 

      using (var fs = new FileStream(destination_path + "\\" + zipname + ".zip", FileMode.OpenOrCreate)) 
      { 

       using (var zip = new ZipArchive(fs, ZipArchiveMode.Update)) 
       {     

        // Some non important thing 

        foreach (string single_file in list_file_tobackup) 
        { 
         // non important things 

         zip.CreateEntryFromFile(single_file, temp); 

        } 
       } 

      }  
// STEP 2 

それは私がSOに周りに見つけたコードの小さな作品ですが。このコードは、静的クラスに含まれているメソッドの中に含まれ、WPFウィンドウから呼び出されていると言っても大丈夫です(多分)。このコード内で使用されるすべてのリストは静的クラス自体で宣言された静的なプライベートリストなので、メモリ内に残ります。

問題が何ですか?

ソフトウェアが最初の段階(STEP 1)にあるとき、RAMへのメモリの影響はごくわずかです(小さなソフトウェアと同じように)。すべてのファイルが圧縮されて最終的に終了すると(STEP 2)、ソフトウェアは大量のRAMを取り、決して解放しません。

非常に大きなフォルダ(約400 MB)を圧縮しようとすると、ソフトウェアは(方法が終了しても)ほぼ1 GBのRAMに保存します。大きなフォルダを試してみると、クラッシュするだけです(System.OutOfMemoryException)。

ソフトウェアは、小さなフォルダを使用して再度メソッドを実行する場合にのみ、メモリを解放できます。

最初は、メモリリークはメモリに保存された大きなファイルリストによって引き起こされたと考えました。その後、私はVisual Studioのメモリテストツールを使用して、大きなメモリチャンクはすべてZipArchiveクラスに属していることを発見しましたので、より深くデバッグすることはできません。

私は何か間違っているか、単にZipAchiveライブラリでは、私がしなければならないことに十分ではありませんか?

これが最後の場合:余りにも多くのライセンスがなくても、より良い.zipライブラリが無料で使用できますか?

+1

Zip Updateメソッドは、メモリリークの原因となる古いファイルと新しいファイルを保持します。 – jdweng

答えて

0

From MSDN モードを[更新]に設定すると、基本となるファイルまたはストリームが読み取り、書き込み、およびシークをサポートする必要があります。アーカイブ全体の内容はメモリに保持され、アーカイブが破棄されるまで、下位のファイルまたはストリームに書き込まれるデータはありません。

ZipArchiveMode.Createを使用しようとしましたか?

既存のアーカイブを更新する必要がある場合でも、既存のアーカイブをコピーして作成し、新しいエントリを作成することができます。

+0

ZipArchiveMode.Createを使用しています!すべてのファイルは問題なく追加されます。 不幸にも、ソフトウェアが完全に壊れています。私の疑問のスニペットはforeachループの内側にあるので、2回目の実行でそれが以前のzipを上書きするだけです... 私は最後のフレーズを強調しませんでした。あなたはそれをよりよく説明できますか? ZipArchiveMode.Createのインスタンスをもう一度やって、Zipファイルを "更新"するにはどうしたらいいですか?私は不可能だと思う... –

+0

あなたのユースケースに応じて、毎回新しいアーカイブを作成し、以前のものを単純に上書きするのは1つのオプションで、最も簡単です。多数のファイルを含む非常に大きなディレクトリを圧縮しようとしている場合は、2番目のアーカイブファイル(基本的にコピー)を作成し、ファイルが変更されていない場合はzipエントリをコピーして新しいファイルを追加してみます。ただし、これにはdiffなどを実行する必要があります。 – Blackfield

関連する問題