问题Memory leak with java已被回答,但是在.net?
中可能会造成内存泄漏会是什么样的例子?
答案 0 :(得分:0)
for(int i = 0; i < 10; i++)
{
IntPtr imageData = Marshal.AllocHGlobal(1024*1024);
}
这将导致10 MB泄漏的内存,例如。 一切都没有管理可能会泄漏,如果有的话,很难设法泄漏内存。
答案 1 :(得分:0)
据我所知,每次执行特定操作时都可以通过创建单独的AppDomain来“泄漏”内存,并且在操作完成后忘记卸载该AppDomain。至少,他们似乎没有自动卸载: http://nikcodes.com/2013/01/18/understanding-appdomain-unloads-old-lessons-learned-anew/
但有人可能认为这不是内存泄漏,因为AppDomains存储在内部而不是“丢失”。但是,我无法找到获取所有现有AppDomains 的方法和/或检查它们是否仍在使用以卸载它们。此外,它可能会非常讨厌,具体取决于加载到AppDomain中的程序集的大小。
修改强>
您可以列出所有AppDomains,但技术上不在.Net中:
List AppDomains in Process
因此,如果您认为Marshal.AllocHGlobal(1024*1024);
是内存泄漏但不在.Net ,那么“未引用的”AppDomains是内存泄漏,因为解决方案不在.Net 。
<强>; P 强>
有大量的哲学讨论,无论是未使用的引用是否被称为“资源泄漏”而不是“内存泄漏”。对我来说,如果无法访问现有的AppDomain,AppDomain示例可能是真正的内存泄漏。
答案 2 :(得分:0)
虽然技术上不是泄漏,但是当您无意中保留对实际上不再需要的对象的引用时,您仍然可以观察到相同的症状(内存不足)。例如,如果您有先前计算数据的静态缓存:
static List<string> previousResults = new List<string>();
public string GetSomeResult(int arg)
{
string s = DoSomething(arg);
previousResults.Add(s);
return s;
}
非常愚蠢的例子,但它表明了一点:当没有人清除列表时,它将永远增长。我在.NET中称这是一个内存泄漏,即使它在技术上不是一个(因为对象仍然是可寻址的)。有更多微妙的方法来观察相同的行为,你没有看到你仍然保留了引用。
答案 3 :(得分:0)
我在.NET中看到的最常见的内存泄漏是一个永远不会消失的静态对象。这对于Singleton对象很常见,但是由于对静态对象的工作原理的误解也可能是错误的。
内存泄漏的另一个狡猾的例子是注册静态事件。例如,SystemEvents类中的所有事件都是静态的。如果一个对象为此事件注册了自己,那么必须取消注册,否则该对象永远不会被垃圾回收。
当有人注册表单来监听SystemEvents.SessionEnding事件时,我们确实发生了这种情况。这些事件是静态的。它们保留了在事件发生时调用的静态委托列表。即使放置了对象,并且对此对象的所有引用都设置为null,静态事件也将继续保留在该对象上,因此该对象永远不会被垃圾回收。并且由于该对象被保留,它引用的所有对象也保持活跃。
答案 4 :(得分:0)
这是在纯Java中创建真正的内存泄漏(通过运行代码但仍然存储在内存中无法访问的对象)的好方法:
应用程序创建一个长时间运行的线程(或者使用线程池来更快地泄漏)。
线程通过(可选自定义)ClassLoader加载一个类。
该类分配大块内存(例如新字节[1000000]),在静态字段中存储对它的强引用,然后在ThreadLocal中存储对自身的引用。分配额外的内存是可选的(泄漏Class实例就足够了),但它会使泄漏工作更快。
该线程清除对自定义类或从中加载的ClassLoader的所有引用。 重复。