2017-02-10 37 views
1

我正在用C#構建一個不錯的軟件。目標版本:.net 4.5。核心工作之一是構建一個文件列表(包含在根文件夾中的各個目錄和子目錄中),然後一次壓縮一個文件。.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 

這是我身邊已經發現了那麼一點點的代碼。 (可能)說這段代碼包含在一個包含在靜態類中的方法中,並從WPF窗口中調用是很重要的。在這個代碼中使用的所有列表都是靜態類本身聲明的靜態私有列表,所以它們將保留在內存中。

有什麼問題?

當軟件開始時(步驟1),它對RAM的內存影響很小(就像所有普通的小軟件一樣)。在所有文件被壓縮後,最終到達結尾(步驟2),軟件已經採用了大量內存並且永遠不釋放它。

如果我嘗試壓縮一個非常大的文件夾(大約400 MB),軟件將在RAM上保留(即使方法完成時)將近1GB!如果我嘗試更大的文件夾,它會簡單地崩潰(System.OutOfMemoryException)。

只有當我用小文件夾再次運行該方法時,該軟件才能釋放內存。

起初我以爲內存泄漏是由內存中保存的大量文件引起的。然後我使用了Visual Studio內存測試工具,並且我發現所有這些大內存都屬於ZipArchive類,所以我無法進行更深入的調試。

我做錯了什麼或只是ZipAchive庫不夠好,我不得不做什麼?

如果這是最後一個:存在一些更好的.zip庫免費使用,沒有太多的許可證約束?

+1

Zip更新方法將保留可能導致內存泄漏的舊文件和新文件。 – jdweng

回答

0

From MSDN 當您將模式設置爲更新時,底層文件或流必須支持讀取,寫入和查找。整個存檔的內容保存在內存中,並且在存檔被丟棄之前不會將數據寫入底層文件或流。

您是否嘗試過使用ZipArchiveMode.Create?

如果您需要對現有存檔執行更新,仍可以通過複製現有存檔並創建新條目來使用創建。

+0

使用ZipArchiveMode.Create正在工作!所有文件都添加沒有問題。 不幸的是,現在的軟件已經完全壞了:我的問題中的代碼片段在foreach循環中,所以第二次運行時它會覆蓋之前的zip文件... 我沒有理解最後一個短語,你能解釋一下嗎?我怎樣才能做更多的ZipArchiveMode.Create實例來更新壓縮文件,最後只有一個.zip文件和我的所有內容?我認爲這是不可能的... –

+0

根據您的使用情況,每次創建一個新的存檔並簡單地覆蓋以前是一個選項,也是最簡單的選項。如果您試圖壓縮包含大量文件的非常大的目錄,我會嘗試創建第二個壓縮文件(基本上是一個副本),並嘗試複製壓縮文件(如果文件未更改並添加新文件)。但是,這需要您執行差異等。 – Blackfield