C#垃圾收集怪异行为

时间:2015-12-16 16:40:47

标签: c# garbage-collection

我有一段代码加载自定义存储文件(data.00x)并转储它的文件内容(几个文件......)[对于这个例子,我们只说引用的索引包含data.001文件用于导出]

示例:

public void ExportFileEntries(ref List<IndexEntry> filteredIndex, string dataDirectory, string buildDirectory, int chunkSize)
{
    OnTotalMaxDetermined(new TotalMaxArgs(8));

    // For each set of dataId files in the filteredIndex
    for (int dataId = 1; dataId < 8; dataId++)
    {
        OnTotalProgressChanged(new TotalChangedArgs(dataId, string.Format("Exporting selected files from data.00{0}", dataId)));

        // Filter only entries with current dataId into temp index
        List<IndexEntry> tempIndex = GetEntriesByDataId(ref filteredIndex, dataId, SortType.Offset);

        // Determine the path of the data.xxx file being exported from
        string dataPath = string.Format(@"{0}\data.00{1}", dataDirectory, dataId);

        if (File.Exists(dataPath))
        {
            // Load the data.xxx into filestream
            using (FileStream dataFs = new FileStream(dataPath, FileMode.Open, FileAccess.Read))
            {
                // Loop through filex to export
                foreach (IndexEntry indexEntry in tempIndex)
                {
                    int fileLength = indexEntry.Length;

                    OnCurrentMaxDetermined(new CurrentMaxArgs(fileLength));

                    // Set the filestreams position to the file entries offset
                    dataFs.Position = indexEntry.Offset;

                    // Read the file into a byte array (buffer)
                    byte[] fileBytes = new byte[indexEntry.Length];
                    dataFs.Read(fileBytes, 0, fileBytes.Length);

                    // Define some information about the file being exported
                    string fileExt = Path.GetExtension(indexEntry.Name).Remove(0, 1);
                    string buildPath = string.Format(@"{0}\{1}\{2}", buildDirectory, fileExt.ToUpper(), indexEntry.Name);

                    // If needed unencrypt the data (fileBytes buffer)
                    if (XOR.Encrypted(fileExt)) { byte b = 0; XOR.Cipher(ref fileBytes, ref b); }

                    // If no chunkSize is provided, generate default
                    if (chunkSize == 0) { chunkSize = Math.Max(64000, (int)(fileBytes.Length * .02)); }

                    // If the build directory doesn't exist yet, create it.
                    if (!Directory.Exists(Path.GetDirectoryName(buildPath))) { Directory.CreateDirectory(Path.GetDirectoryName(buildPath)); }

                    using (FileStream buildFs = new FileStream(buildPath, FileMode.Create, FileAccess.Write))
                    {
                        using (BinaryWriter bw = new BinaryWriter(buildFs, encoding))
                        {
                            for (int byteCount = 0; byteCount < fileLength; byteCount += Math.Min(fileLength - byteCount, chunkSize))
                            {
                                bw.Write(fileBytes, byteCount, Math.Min(fileLength - byteCount, chunkSize));
                                OnCurrentProgressChanged(new CurrentChangedArgs(byteCount, ""));
                            }
                        }
                    }

                    OnCurrentProgressReset(EventArgs.Empty);

                    fileBytes = null;
                }
            }
        }
        else { OnError(new ErrorArgs(string.Format("[ExportFileEntries] Cannot locate: {0}", dataPath))); }
    }

    OnTotalProgressReset(EventArgs.Empty);

    GC.Collect();
}

data.001存储大约12k个文件,大多数是非常小的.jpg图片等等...对于大约上半年的导出过程gc收集得很好,但是无处不在朝向下半部分gc刚刚停止给出废话的出口过程。

如果我不在方法结束时发出GC.Collect(),那么该工具位于255mb左右,但如果我确实调用它,则会降低到大约14mb。我要问的是,对我编写方法的方式有哪些明显的改进(以提高gc性能)?

0 个答案:

没有答案