.NET 1.1中的内存泄漏 [英] Memory Leak in .NET 1.1

查看:64
本文介绍了.NET 1.1中的内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我们庞大的.NET 1.1 C#应用程序中检测到内存泄漏但是

无法直接对它们进行本地化。所以我已经将代码缩减为

以下控制台应用程序:


使用System;

使用System.IO;


命名空间MemLeak

{

class MemLeak

{

[STAThread]

static void Main(string [] args)

{

try

{

抛出新的NullReferenceException();

}

catch

{

}


for(int i = 0; i< 1000; i ++)

{

using(StreamWriter newMasterfile =

new StreamWriter(@" c:\ XXX.tmp"))

{

newMasterfile.Close();

}

}


Console.ReadLine();

}

}

}


您还必须创建一个App.config。文件由

VS2003分发到应用程序目录中,其中包含应用程序名称

后跟.config。可能有任何内容,文件可能是空的

- 这不会影响我们的结果。


编译发布配置,你会看到像

" NetMemoryProfiler"这样的工具。在

" Console.ReadLine"中保留了近1000个StreamWriter。你可以随心所欲地等待 - 他们永远不会被释放。如果你没有这样的工具:增加循环次数。

然后你可以使用任务管理器来查看内存是如何增长的(看看

虚拟内存!)。通过无限循环,将有一个Out of

虚拟内存。最后的错误。


这个问题不仅限于StreamWriter。我们已经看到了这个用于

的数据库对象,简单的字符串和其他。


我们用几个不同的Windows XP SP2系统对它进行了测试>
配置。还有最新的Windows和.NET修复程序。


有趣的是:使用Debug

配置时不会出现泄漏。您也可以省略异常或App.config

文件。在这些情况下,将正确释放内存。但是我们将在发布中加入
comile配置,使用App.config和例外

是不可避免的。


最后一个选项是切换属性[STAThread]

" [MTAThread]"。小例子中的内存是好的(为什么?)以及我们庞大的应用程序中的
。但是我不确定我们使用的COM组件。

所以我更喜欢[STAThread]。属性。


有些方法可以告诉gabage收集器清理

up:" GC.GetTotalMemory(...)", " GC.WaitForPendingFinalizers()"和

" GC.Collect()"。你可以在小例子中找到组合来消除内存。但这是非常不可靠的,并且在我们的大型应用程序中无法正常工作

,其中后期绑定和远程处理使用了



经过几天的反复试验,我真的在我的智慧结束这个问题上结束了

。那么有谁可以帮助我吗?


非常感谢提前

Martin Gaus

解决方案

2006年5月28日05:00:33 -0700, MA ***** @ gmx。 net 写道:

我在我们庞大的.NET 1.1 C#应用程序中检测到了内存泄漏,但
无法直接对它们进行本地化。所以我已经将代码缩减到以下控制台应用程序:

使用System;
使用System.IO;

名称空间MemLeak
{MemLeak类
{
[STAThread]
static void Main(string [] args)
{
尝试
{
抛出新的NullReferenceException();
}
为(int i = 0; i< 1000; i ++)抓住了
{
}

{
使用(StreamWriter newMasterfile =
new StreamWriter(@" c:\ XXXX.tmp"))
{
newMasterfile.Close(); <


Console.ReadLine();
}
}
}

你也必须创建一个App.config由VS2003分发到应用程序目录中的文件,其中包含应用程序的名称
,后跟.config。可能有任何内容,文件也可能是空的 - 这不会影响我们的结果。

编译发布。配置,你会看到像
NetMemoryProfiler这样的工具。在
Console.ReadLine中保留了近1000个StreamWriter。你可以随心所欲地等待 - 他们永远不会被释放。如果你没有这样的工具:增加循环次数。
然后你可以使用任务管理器来查看内存的增长情况(看看虚拟内存!)。通过无限循环,将存在Out of
虚拟存储器。最后的错误。

这个问题不仅限于StreamWriter。我们已经看到了这个数据库对象,简单的字符串和其他。

我们已经使用具有不同
配置的几个Windows XP SP2系统测试了这个。还有最新的Windows和.NET修复程序。

有趣的是:当你使用Debug
配置时不会有泄漏。您也可以省略异常或App.config
文件。在这些情况下,将正确释放内存。但我们会在发布中加入配置,使用App.config和例外
无法避免。

最后一个选项是切换属性[STAThread]。
[MTAThread]。小例子中的内存是好的(为什么?)以及我们庞大的应用程序中的内存。但是我不确定我们使用的COM组件。
所以我更喜欢[STAThread]。属性。

有一些方法可以告诉gabage收集器清理
up:" GC.GetTotalMemory(...)"" GC.WaitForPendingFinalizers()" ;和
GC.Collect()。您可以在小例子中找到组合以消除内存。但这是非常不可靠的,并且在我们使用后期绑定和远程处理的巨大应用程序中无法正常工作。

经过几天的反复试验,我真的在我的智慧结束了这个问题。那么有谁可以帮助我吗?

非常感谢提前
Martin Gaus




只是想知道(不试试)


newMasterfile.Close();

newMasterfile = null;


这有什么区别?

-

Ludwig Stuyck
使用(StreamWriter newMasterfile = new StreamWriter(@c:\ XXXX.tmp )

{

newMasterfile.Close();

newMasterfile = null;

}


这样的事情是不可能的。编译器抱怨

" newMasterfile"写保护。但是我用

测试了以下结果(漏洞):


StreamWriter newMasterfile = new StreamWriter(@" c:\ XXX.tmp");

newMasterfile.Close();

newMasterfile = null;


这里似乎没有内存泄漏(至少在我的系统上)..尝试

包含的代码..在我的系统上它可以达到大约8mb的内存..然后

变平(如果有内存泄漏,我可以向你保证,运行

10,000,000次而不是1000将显示内存的严重差异

用法)


垃圾收集器很可能还没有收集这些物品

(并且没有创建新项目,并且对内存没有压力)

已经分配了为什么要快点?)。一旦施加了一些压力

,gc似乎就会毫无问题地接收它们


在你的大型系统中我给你提到的第一个看的东西

将是大对象堆,看它是否正在增长..如果是的话,什么是

呢?


干杯,


Greg Young

MVP - C#


使用系统;

使用System.IO;


命名空间MemLeak

{

class MemLeak

{

[STAThread]

static void Main(string [] args)

{

try

{

抛出新的NullReferenceException();

}

catch

{

}


for(int i = 0; i< 10000000; i ++)

{

using(StreamWriter newMasterfile =

new StreamWriter(@" c:\ XXXX.tmp"))

{

newMasterfile.Close();

}

}


Console.ReadLine(); < br $>
}

}

}

< MA ***** @ gmx.net>在消息中写道

news:11 ********************** @ j33g2000cwa.googlegr oups.com ...

我在我们庞大的.NET 1.1 C#应用程序中检测到了内存泄漏,但
无法直接对它们进行本地化。所以我已经将代码缩减到以下控制台应用程序:

使用System;
使用System.IO;

名称空间MemLeak
{MemLeak类
{
[STAThread]
static void Main(string [] args)
{
尝试
{
抛出新的NullReferenceException();
}
为(int i = 0; i< 1000; i ++)抓住了
{
}

{
使用(StreamWriter newMasterfile =
new StreamWriter(@" c:\ XXXX.tmp"))
{
newMasterfile.Close(); <


Console.ReadLine();
}
}
}

你也必须创建一个App.config由VS2003分发到应用程序目录中的文件,其中包含应用程序的名称
,后跟.config。可能有任何内容,文件也可能是空的 - 这不会影响我们的结果。

编译发布。配置,你会看到像
NetMemoryProfiler这样的工具。在
Console.ReadLine中保留了近1000个StreamWriter。你可以随心所欲地等待 - 他们永远不会被释放。如果你没有这样的工具:增加循环次数。
然后你可以使用任务管理器来查看内存的增长情况(看看虚拟内存!)。通过无限循环,将存在Out of
虚拟存储器。最后的错误。

这个问题不仅限于StreamWriter。我们已经看到了这个数据库对象,简单的字符串和其他。

我们已经使用具有不同
配置的几个Windows XP SP2系统测试了这个。还有最新的Windows和.NET修复程序。

有趣的是:当你使用Debug
配置时不会有泄漏。您也可以省略异常或App.config
文件。在这些情况下,将正确释放内存。但我们会在发布中加入配置,使用App.config和例外
无法避免。

最后一个选项是切换属性[STAThread]。
[MTAThread]。小例子中的内存是好的(为什么?)以及我们庞大的应用程序中的内存。但是我不确定我们使用的COM组件。
所以我更喜欢[STAThread]。属性。

有一些方法可以告诉gabage收集器清理
up:" GC.GetTotalMemory(...)"" GC.WaitForPendingFinalizers()" ;和
GC.Collect()。您可以在小例子中找到组合以消除内存。但这是非常不可靠的,并且在我们使用后期绑定和远程处理的巨大应用程序中无法正常工作。

经过几天的反复试验,我真的在我的智慧结束了这个问题。那么有谁可以帮助我吗?

非常感谢提前
Martin Gaus



I''ve detected memory leaks in our huge .NET 1.1 C# application but
couldn''t localize them directly. So I''ve reduced the code to the
following console application:

using System;
using System.IO;

namespace MemLeak
{
class MemLeak
{
[STAThread]
static void Main(string[] args)
{
try
{
throw new NullReferenceException();
}
catch
{
}

for(int i=0; i<1000; i++)
{
using(StreamWriter newMasterfile =
new StreamWriter(@"c:\XXX.tmp"))
{
newMasterfile.Close();
}
}

Console.ReadLine();
}
}
}

Also you have to create an "App.config" file which is distributed by
VS2003 into the application directory with the name of the application
followed by ".config". There may be any content, the file can be empty
too - this will not influence our result.

Compile the "Release" configuration and you''ll see with a tool like
"NetMemoryProfiler" that there are almost 1000 StreamWriter reserved at
"Console.ReadLine". You can wait as long as you want - they''ll never be
freed. If you don''t have such a tool: increase the number of loops.
Then you can use the task manager to see how the memory grows (look at
the virtual memory!). With an endless loop there will be an "Out of
virtual memory" error at the end.

This problem is not only bounded to StreamWriter. We''ve seen this for
database objects, simple strings and other.

We have tested this with several Windows XP SP2 Systems with different
configurations. Also with the latest fixes for Windows and .NET.

The funny thing: there will be no leaks when you use the "Debug"
configuration. Also you can omit the exception or the "App.config"
file. In these cases the memory will be freed correctly. But we will
comile in "Release" configuration, use the "App.config" and Exceptions
can''t be avoided.

The last option is to switch the attribute "[STAThread]" to
"[MTAThread]". The memory is ok in the small example (why?) and also in
our huge application. But I''m not sure with the COM-components we use.
So I prefer the "[STAThread]" attribute.

There are some methods which you can tell the gabage collector to clean
up: "GC.GetTotalMemory(...)", "GC.WaitForPendingFinalizers()" and
"GC.Collect()". You can find combinations in the small example to get
rid of the memory. But this is very unreliable and will not work
correctly in our huge application where late binding and remoting is
used.

After some days of trial and error, I am really at my wits'' end over
this problem. So is there anybody who can help me?

Many thanks in advance
Martin Gaus

On 28 May 2006 05:00:33 -0700, MA*****@gmx.net wrote:

I''ve detected memory leaks in our huge .NET 1.1 C# application but
couldn''t localize them directly. So I''ve reduced the code to the
following console application:

using System;
using System.IO;

namespace MemLeak
{
class MemLeak
{
[STAThread]
static void Main(string[] args)
{
try
{
throw new NullReferenceException();
}
catch
{
}

for(int i=0; i<1000; i++)
{
using(StreamWriter newMasterfile =
new StreamWriter(@"c:\XXX.tmp"))
{
newMasterfile.Close();
}
}

Console.ReadLine();
}
}
}

Also you have to create an "App.config" file which is distributed by
VS2003 into the application directory with the name of the application
followed by ".config". There may be any content, the file can be empty
too - this will not influence our result.

Compile the "Release" configuration and you''ll see with a tool like
"NetMemoryProfiler" that there are almost 1000 StreamWriter reserved at
"Console.ReadLine". You can wait as long as you want - they''ll never be
freed. If you don''t have such a tool: increase the number of loops.
Then you can use the task manager to see how the memory grows (look at
the virtual memory!). With an endless loop there will be an "Out of
virtual memory" error at the end.

This problem is not only bounded to StreamWriter. We''ve seen this for
database objects, simple strings and other.

We have tested this with several Windows XP SP2 Systems with different
configurations. Also with the latest fixes for Windows and .NET.

The funny thing: there will be no leaks when you use the "Debug"
configuration. Also you can omit the exception or the "App.config"
file. In these cases the memory will be freed correctly. But we will
comile in "Release" configuration, use the "App.config" and Exceptions
can''t be avoided.

The last option is to switch the attribute "[STAThread]" to
"[MTAThread]". The memory is ok in the small example (why?) and also in
our huge application. But I''m not sure with the COM-components we use.
So I prefer the "[STAThread]" attribute.

There are some methods which you can tell the gabage collector to clean
up: "GC.GetTotalMemory(...)", "GC.WaitForPendingFinalizers()" and
"GC.Collect()". You can find combinations in the small example to get
rid of the memory. But this is very unreliable and will not work
correctly in our huge application where late binding and remoting is
used.

After some days of trial and error, I am really at my wits'' end over
this problem. So is there anybody who can help me?

Many thanks in advance
Martin Gaus



just wondering (without trying it)

newMasterfile.Close();
newMasterfile=null;

does this make any difference?
--
Ludwig Stuyck
http://www.coders-lab.be


using(StreamWriter newMasterfile = new StreamWriter( @"c:\XXX.tmp" ))
{
newMasterfile.Close();
newMasterfile = null;
}

Something like this is not possible. The compiler complains that
"newMasterfile" is write protected. But I''ve tested the following with
the same result (with leaks):

StreamWriter newMasterfile = new StreamWriter( @"c:\XXX.tmp" );
newMasterfile.Close();
newMasterfile = null;


There does not seem to be a memory leak here (atleast on my system) .. try
the included code .. on my system it gets up to about 8mb of memory .. then
flattens out (if there were a memory leak here I can assure you that running
10,000,000 times as opposed to 1000 would show a severe difference in memory
usage)

Most likely the garbage collector has just not collected those items yet
(and with no new items being created, and no pressure on the memory it
already has allocated why should it hurry?). Once some pressure is placed
upon it the gc seems to pick things up without issue

In your larger system my first place to look given the things you mention
would be the large object heap to see if it is growing .. if it is, whats in
it?

Cheers,

Greg Young
MVP - C#

using System;
using System.IO;

namespace MemLeak
{
class MemLeak
{
[STAThread]
static void Main(string[] args)
{
try
{
throw new NullReferenceException();
}
catch
{
}

for(int i=0; i<10000000; i++)
{
using(StreamWriter newMasterfile =
new StreamWriter(@"c:\XXX.tmp"))
{
newMasterfile.Close();
}
}

Console.ReadLine();
}
}
}
<MA*****@gmx.net> wrote in message
news:11**********************@j33g2000cwa.googlegr oups.com...

I''ve detected memory leaks in our huge .NET 1.1 C# application but
couldn''t localize them directly. So I''ve reduced the code to the
following console application:

using System;
using System.IO;

namespace MemLeak
{
class MemLeak
{
[STAThread]
static void Main(string[] args)
{
try
{
throw new NullReferenceException();
}
catch
{
}

for(int i=0; i<1000; i++)
{
using(StreamWriter newMasterfile =
new StreamWriter(@"c:\XXX.tmp"))
{
newMasterfile.Close();
}
}

Console.ReadLine();
}
}
}

Also you have to create an "App.config" file which is distributed by
VS2003 into the application directory with the name of the application
followed by ".config". There may be any content, the file can be empty
too - this will not influence our result.

Compile the "Release" configuration and you''ll see with a tool like
"NetMemoryProfiler" that there are almost 1000 StreamWriter reserved at
"Console.ReadLine". You can wait as long as you want - they''ll never be
freed. If you don''t have such a tool: increase the number of loops.
Then you can use the task manager to see how the memory grows (look at
the virtual memory!). With an endless loop there will be an "Out of
virtual memory" error at the end.

This problem is not only bounded to StreamWriter. We''ve seen this for
database objects, simple strings and other.

We have tested this with several Windows XP SP2 Systems with different
configurations. Also with the latest fixes for Windows and .NET.

The funny thing: there will be no leaks when you use the "Debug"
configuration. Also you can omit the exception or the "App.config"
file. In these cases the memory will be freed correctly. But we will
comile in "Release" configuration, use the "App.config" and Exceptions
can''t be avoided.

The last option is to switch the attribute "[STAThread]" to
"[MTAThread]". The memory is ok in the small example (why?) and also in
our huge application. But I''m not sure with the COM-components we use.
So I prefer the "[STAThread]" attribute.

There are some methods which you can tell the gabage collector to clean
up: "GC.GetTotalMemory(...)", "GC.WaitForPendingFinalizers()" and
"GC.Collect()". You can find combinations in the small example to get
rid of the memory. But this is very unreliable and will not work
correctly in our huge application where late binding and remoting is
used.

After some days of trial and error, I am really at my wits'' end over
this problem. So is there anybody who can help me?

Many thanks in advance
Martin Gaus



这篇关于.NET 1.1中的内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆