相关疑难解决方法(0)

缓存反射数据

缓存从反射获得的昂贵数据的最佳方法是什么?例如,大多数快速序列化程序都会缓存此类信息,因此无需在每次遇到相同类型时进行反映.他们甚至可以生成一个动态方法,从类型中查找.

之前.net 4

传统上我使用了普通的静态字典.例如:

private static ConcurrentDictionary<Type, Action<object>> cache;

public static DoSomething(object o)
{
    Action<object> action;
    if(cache.TryGetValue(o.GetType(), out action)) //Simple lookup, fast!
    {
        action(o);
    }
    else
    {
        // Do reflection to get the action
        // slow
    }
} 
Run Code Online (Sandbox Code Playgroud)

这会泄漏一点内存,但是因为它只对每种类型和类型执行一次,只要AppDomain我不认为这是一个问题.

自.net 4

但是现在.net 4引入了用于动态类型生成的可收集组件.如果我曾经使用过可DoSomething收集组件中声明的对象,那么组件将不会被卸载.哎哟.

那么在.net 4中缓存每种类型信息的最佳方法是什么?没有遇到这个问题?我能想到的最简单的解决方案是:

private static ConcurrentDictionary<WeakReference, TCachedData> cache.
Run Code Online (Sandbox Code Playgroud)

IEqualityComparer<T>我必须使用它会表现得非常奇怪,也可能违反合同.我不确定查找的速度有多快.

另一个想法是使用到期超时.可能是最简单的解决方案,但感觉有点不雅.


在类型作为通用参数提供的情况下,我可以使用嵌套的泛型类,它不应该遇到这个问题.但是如果在变量中提供类型,则它不起作用.

class MyReflection
{
    internal Cache<T>
    {
        internal static TData data;
    }

    void DoSomething<T>()
    {
        DoSomethingWithData(Cache<T>.data);
        //Obviously simplified, should have …
Run Code Online (Sandbox Code Playgroud)

.net c# garbage-collection .net-assembly

49
推荐指数
1
解决办法
8454
查看次数

从静态对象中包含的C#字典中释放内存

我有一些WCF Web服务的问题(一些转储,内存泄漏等),我运行一个profillng工具(ANTS内存配置文件).

只是为了发现即使处理结束(我运行特定测试然后停止),第2代也是Web服务内存的25%.我追踪到这个内存,发现我有一个字典对象,里面有(null,null)项,带有-1个哈希码.

Web服务的工作流意味着在特定处理期间添加项目然后从字典中删除(只是简单AddRemove).没有大碍.但似乎在删除所有项目后,字典中充满了(null,null)KeyValuePairs.事实上,成千上万的它们占据了很大一部分内存并最终发生了溢出,相应的强制应用程序池回收和DW20.exe获得了它可以获得的所有CPU周期.

实际上是字典Dictionary<SomeKeyType, IEnumerable<KeyValuePair<SomeOtherKeyType, SomeCustomType>>>(System.OutOfMemoryException,因为大字典)所以我已经检查过是否存在某种引用.

字典包含在一个静态对象中(通过处理使其可以访问不同的处理线程)所以从这个问题和更多(静态成员是否得到垃圾收集?)我理解为什么该字典在第2代.但这是那些原因(null,null)?即使我从字典中删除项目,内存中也会总是占用一些东西?

这不是像这个问题中的速度问题从C#中的大型数据结构中释放内存.似乎记忆永远不会被回收.

有什么我可以做的事实上从字典中删除项目,而不是继续填充(null,null)对吗?还有什么我需要检查的吗?

c# garbage-collection memory-leaks memory-management

16
推荐指数
2
解决办法
9929
查看次数

可以在静态字段中引用自身的类进行垃圾回收吗?

public class MyClass {
  private static MyClass heldInstance;

  public MyClass() {
    heldInstance = this;
  }
}
Run Code Online (Sandbox Code Playgroud)

假设MyClass的一个实例没有以任何其他方式生根,那么这里的私有静态引用是否会阻止它被垃圾收集?

c# static garbage-collection private

6
推荐指数
1
解决办法
716
查看次数

是否收集了字符串和静态字段?

垃圾收集器何时回收字符串和静态字段?

我问这个是因为我知道staticASP.NET中的s总是有效的.

.net c# clr

5
推荐指数
2
解决办法
1150
查看次数

垃圾收集器何时收集单身人士?

SomeSingleton在C#中有一些类(如果重要,则为.NET 3.5)和代码:

foo()
{
    ...
    SomeSingleton.Instance.DoSomething();
    ...
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:垃圾收集器什么时候会收集这个Singleton对象?

ps:SomeSingleton的代码:

    private static SomeSingleton s_Instance = null;
    public static SomeSingleton Instance
    {
        get 
        {
            if (s_Instance == null)
            {
                lock (s_InstanceLock)
                {
                    if (s_Instance == null)
                    {
                        s_Instance = new SomeSingleton();
                    }
                }
            }
            return s_Instance;
        }
    }
Run Code Online (Sandbox Code Playgroud)

感谢帮助!

编辑(附说明):

在Widnows服务中我有代码:

   ...
   FirstSingleton.Instance.DoSomething();
   ...

public class FirstSingleton
{
    (Instance part the same as in SomeSingleton)
    public void DoSomething()
    {
        SomeSingleton.Instance.DoSomething();
    }
}
Run Code Online (Sandbox Code Playgroud)

我想要实现的目标:我不关心FirstSingleton会发生什么,但SomeSingleton首先使用它启动Timer,所以我需要SomeSingleton存在(所以定时器可以在每个时间段运行新线程),只要我的服务是运行.

正如我从你的答案中理解的那样,所有这一切都会发生,因为对我的FirstSingleton和SomeSingleton的引用是静态的,并且在服务停止之前GC不会收集单身人士,我是对的吗?:)

.net c# singleton garbage-collection

4
推荐指数
1
解决办法
3504
查看次数

在非静态方法中使用静态成员是否会导致内存泄漏?

DoSomething()方法会导致内存泄漏吗?

public static class AppContext
{
   public static int ApplicationStateId {get; set} 
   ...
} 
public class MyService
{
     public void DoSomething()
     {
        ....
        if(AppContext.ApplicationStateId == 1) 
        {
             //do something
        } 
     }
}
Run Code Online (Sandbox Code Playgroud)
var service = new MyService();
service.DoSomething();
Run Code Online (Sandbox Code Playgroud)

这意味着静态变量及其引用的所有内容永远不会被垃圾收集。

Michael在 .NET 中导致内存泄漏的 8 种方法中说道。

c# static memory-leaks

3
推荐指数
1
解决办法
2208
查看次数