【问题标题】:Nested objects causing lost memory "leak" in .NET 4 LinkedList嵌套对象导致 .NET 4 LinkedList 中丢失的内存“泄漏”
【发布时间】:2012-05-30 13:15:31
【问题描述】:

编辑:请忽略这个问题,这是一个 PBCAK 程序员错误。

第 1 部分

如何纠正此代码中的内存泄漏?

第 2 部分

如果解决方案包括将Dispose 添加到SummaryEntity,如果我有第二个引用它的列表(摘要摘要),我应该如何处置该对象?假设我想在摘要摘要中保留 10 个最新的 SummaryEntities

代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Concurrent;

namespace TestDoesLinkedListLeak
{
    public class SummaryEntity
    {
        public object PlaceHolder { get; set; }
        /// <summary>
        /// Note: This is a Field instead of a Property to support Interlockd methods
        /// </summary>
        public int ReferenceCount;
        public int Value;
        public int? PreviousValue { get; set; }
    }
    class FrequencyOfMatchedHash : Dictionary<int, SummaryEntity> 
    {
        private object frequencyOfMatchedHashLock;

        public void AddRecordHash(int hashCode, int value, object placeHolder)
        {
            SummaryEntity se = null;
            try
            {
                se = new SummaryEntity();
                se.ReferenceCount = 1;
                se.PlaceHolder = placeHolder;
                se.Value = value;

                lock (this.frequencyOfMatchedHashLock)
                {
                    if (this.ContainsKey(hashCode))
                    {
                        System.Threading.Interlocked.Add(ref this[hashCode].Value, value);
                        System.Threading.Interlocked.Increment(ref  this[hashCode].ReferenceCount);
                    }
                    else
                    {
                        this.Add(hashCode, se);
                    }
                }

                //this.AddOrUpdate(hashCode, se ,
                // (k, v) => 
                //     {
                //         System.Threading.Interlocked.Add(ref v.Value , value);
                //         System.Threading.Interlocked.Increment(ref v.ReferenceCount); 
                //         return v;
                //     });
            }
            finally
            {
                //se.Dispose();

            }
        }
    }
    class LLDateNode //:IDisposable
    {
        public FrequencyOfMatchedHash FrequencyOfMatch { get; set; }
        public DateTime Date { get; set; }

        public override string ToString()
        {
            return Date + " Count:" + FrequencyOfMatch.Count;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Console.WriteLine("start");
                Console.WriteLine("Total Memory: {0}  Forced Collect: {1}", GC.GetTotalMemory(false), GC.GetTotalMemory(true));
                LinkedList<LLDateNode> tmp = new LinkedList<LLDateNode>();
                for (int i = 0; i < 111111; i++)
                {
                   // Console.Write(".");
                    tmp.AddFirst(new LLDateNode() { Date = DateTime.UtcNow, FrequencyOfMatch = new FrequencyOfMatchedHash() });
                }
                Console.WriteLine();
                Console.WriteLine("Done create, now delete");
                Console.WriteLine("Total Memory: {0}  Forced Collect: {1}", GC.GetTotalMemory(false), GC.GetTotalMemory(true));
                Console.WriteLine();

                for (int i = 0; i < tmp.Count; i++)
                {
                    //Console.Write("x");
                    tmp.RemoveFirst();
                }
                Console.WriteLine();
                Console.WriteLine("End of program");
                Console.WriteLine("Total Memory: {0}  Forced Collect: {1}", GC.GetTotalMemory(false), GC.GetTotalMemory(true));
                Console.ReadLine();
                Console.ReadLine();
                Console.ReadLine();
                Console.ReadLine();

            }
            catch
            {

            }
        }
    }
}

输出

start
Total Memory: 186836  Forced Collect: 106656

Done create, now delete
Total Memory: 11222752  Forced Collect: 11217844


End of program
Total Memory: 11226036  Forced Collect: 5662320

【问题讨论】:

  • @EugenRieck 我不应该发布属性ReferenceCount。它是一个开发中的应用程序的摘录。 More info not immediately relevant to this question:我有一本按哈希码跟踪对象的字典(此处未列出),还有一个按日期跟踪对象的链表。随着对象从链接列表中老化,我将它们从字典中删除。字典或多或少是一个时间点的汇总和滚动聚合。引用计数是“活动”并包含在摘要中的所有链表项的总和。

标签: c# .net memory-leaks linked-list dispose


【解决方案1】:

我可能是错的,但是我认为当您调用 tmp.RemoveFirst() 时,tmp.Count 的大小会变小,而 i 会不断增长。因此,您只删除了一半 Dictionary。不要增加i 或将tmp.Count 放入变量中,然后在循环条件中使用它。考虑到您最后一次 Force Collect 的大小约为一半,这看起来可能是您的问题。

【讨论】:

  • 你是对的。我正在尝试重现我的应用程序中的内存泄漏并且遇到了问题。我以为我已经解决了这个问题,回到了绘图板上。
猜你喜欢
  • 2022-10-17
  • 2014-06-20
  • 2021-02-26
  • 2018-07-15
  • 2015-12-26
  • 1970-01-01
  • 1970-01-01
  • 2015-05-12
  • 2021-06-19
相关资源
最近更新 更多