3

已经回答了 java的内存泄漏问题,但是在 .net 中是否可能造成内存泄漏?

什么是一个例子?

4

5 回答 5

0
for(int i = 0; i < 10; i++)
{
    IntPtr imageData = Marshal.AllocHGlobal(1024*1024);
}

例如,这将导致 10 MB 内存泄漏。所有不受管理的东西都可能泄漏,如果有的话,很难让管理的东西泄漏内存。

于 2013-06-29T12:13:41.237 回答
0

据我所知,您可以通过在每次执行特定操作时创建一个单独的 AppDomain 来“泄漏”内存,并在操作完成后忘记卸载该 AppDomain。至少,它们似乎不会自动卸载:http: //nikcodes.com/2013/01/18/understanding-appdomain-unloads-old-lessons-learned-anew/

但有人可能会争辩说这不是内存泄漏,因为 AppDomain 存储在内部而不是“丢失”。但是,我找不到获取所有现有 AppDomain和/或检查它们是否仍在使用以卸载它们的方法。此外,它可能会变得非常糟糕,具体取决于加载到 AppDomain 中的程序集的大小。

编辑: 您可以列出所有 AppDomains,但它在技术上不在 .Net 中: List AppDomains in Process 所以如果您认为Marshal.AllocHGlobal(1024*1024);是内存泄漏但不在 .Net 中,那么“未引用” AppDomains 是内存泄漏,因为解决方案不在.Net

; 磷

那里有大量的哲学讨论,是否将未使用的引用称为“资源泄漏”而不是“内存泄漏”。对我来说,如果无法访问现有的 AppDomain,那么 AppDomain 示例可能是真正的内存泄漏。

于 2013-10-28T16:25:58.080 回答
0

虽然从技术上讲不是泄漏,但当您无意中保留对您实际上不再需要的对象的引用时,您仍然可以观察到相同的症状(内存不足)。例如,如果您有以前计算的数据的静态缓存:

static List<string> previousResults = new List<string>();

public string GetSomeResult(int arg)
{
    string s = DoSomething(arg);
    previousResults.Add(s);
    return s;
}

非常愚蠢的例子,但它说明了一点:当没有人清除列表时,它会永远增长。我称这是 .NET 中的内存泄漏,即使它在技术上不是一个(因为对象仍然是可寻址的)。有更微妙的方法可以观察相同的行为,您首先看不到您仍然保留引用。

于 2013-10-31T10:37:00.953 回答
0

我在 .NET 中看到的最常见的内存泄漏是一个永远不会消失的静态对象。这对于 Singleton 对象很常见,但也可能是由于误解了静态对象的工作原理而导致的错误。

另一个更隐秘的内存泄漏示例是注册静态事件。例如,SystemEvents类中的所有事件都是静态的。如果一个对象为这个事件注册了自己,它必须注销自己,否则该对象将永远不会被垃圾回收。

当有人注册一个表单来监听SystemEvents.SessionEnding事件时,我们实际上发生了这种情况。这些事件是静态的。它们保留在事件发生时调用的静态委托列表。即使对象已被释放,并且您对该对象的所有引用都设置为 null,静态事件仍将继续持有它,因此该对象永远不会被垃圾回收。并且由于该对象被保留,它引用的所有对象也保持活动状态。

于 2014-10-07T16:29:39.397 回答
0

这是在纯 Java 中创建真正的内存泄漏(运行代码无法访问但仍存储在内存中的对象)的好方法:

应用程序创建一个长时间运行的线程(或使用线程池更快地泄漏)。

线程通过(可选自定义)ClassLoader 加载一个类。

该类分配一大块内存(例如新字节[1000000]),在静态字段中存储对它的强引用,然后在ThreadLocal 中存储对自身的引用。分配额外的内存是可选的(泄漏 Class 实例就足够了),但它会使泄漏工作得更快。

该线程清除对自定义类或从中加载它的 ClassLoader 的所有引用。重复。

信用:https ://stackoverflow.com/a/6471947/6017500

于 2018-05-07T13:21:57.957 回答