不是内存泄漏,但可能是坏事 [英] Not axactly a memory leak but can be bad

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

问题描述



我最终缩小了我的代码到这种情况,相当多(不是全部)

我的CMyClass对象在每次运行此函数后都得到了保持

显示NumberEd编辑框的简单网页。我的记忆配置文件显示,这些实例在3轮GC收集中幸存下来 - 这不是我预期的b $ b。在我的真实代码中,CMyClass占用了大量的内存,而且他们只是分享了另一个类的一个立场,我没有足够的内存保持

多于一个正义记忆中的一些。请注意,最终我的

CMyClass在演示这个问题方面有很大的不同,而且它没有存在问题。\\ b
问题不存在。有趣的是,如果我再次运行页面,

旧的悬空部分被摧毁,新的部分变得悬空。我是否错过了关于GC的事情?
我是否需要为这些类明确实现并调用

dispose而不是依赖GC来及时收集它?

显然不知何故这些对象可以在自动生存下来

集合...处理它会有所帮助。感谢您的评论和帮助。


内部类CMyClass

{

ArrayList m_array = new ArrayList(50000);

私有字符串m_idStr;

私有guid m_guid;

内部CMyClass(int n)

{

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

m_array.Add(Guid.NewGuid());


m_guid = Guid.NewGuid();

m_idStr = m_guid.ToString();

}


内部Guid id

{

get {return(Guid)m_array [0]; }

}


~CMyClass()

{

// Trace.Write(m_guid ,m_idStr);

}


}

private void RunBtn_Click(object sender,System.EventArgs e)

{

ResultEd.Text ="" ;;

试试

{


for(int i = 0; i< int.Parse(NumberEd.Text); ++ i)

{


Hashtable table = new Hashtable(100);

ArrayList ids = new ArrayList(10);

for(int j = 0; j< 10; ++ j)

{

Guid id = Guid.NewGuid();

table [id] = null;

ids.Add(id );
}

for(int k = 0; k< 10; ++ k)

{

foreach(guid id in id)

{

table [id] = new CMyClass(10);

}


CMyClass myobj;

foreach(ids id中的guid id)

{

myobj =(CMyClass)表[ id];

myobj.id.ToString();

}

} // for k

} // for

}

catch(Exception ex)

{

ResultEd.Text = ex.Message +" ... CallSTack:" +

ex.StackTrace;

}


GC.Collect();

GC。 WaitForPendingFinalizers();

GC.Collect();


GC.WaitForPendingFinalizers();

GC.Collect();


ResultEd.Text =" Done";

}


I finally narrowed down my code to this situation, quite a few (not all) of
my CMyClass objects got hold up after each run of this function via the
simple webpage that shows NumberEd editbox. My memory profile shows that
those instances survive 3 rounds of GC collections - it''s not what I
expected. In my real code, CMyClass occupies big amount of memory and they
all share one stance of another class that I don''t have enough memory hold
more than a just a few in the memory. Notice that the finalizaer the my
CMyClass makes a big difference in demonstrating this issue, w/o it the
problem doesn''t exist. The interesting thing is if I run the page again,
the old dangling ones got destroyed and the new ones become dangling. Am I
missing something about the GC? Do I need to explicitly implement and call
dispose for these classes instead of relying on GC to promptly collect it?
Apparently somehow these objects can survive the automatic
collections...disposing it would help. Thanks for your comment and help.

internal class CMyClass
{
ArrayList m_array = new ArrayList( 50000 );
private string m_idStr;
private Guid m_guid;
internal CMyClass( int n )
{
for( int i = 0; i < n; ++i )
m_array.Add( Guid.NewGuid() );

m_guid = Guid.NewGuid();
m_idStr = m_guid.ToString();
}

internal Guid id
{
get{ return (Guid ) m_array[ 0 ]; }
}

~CMyClass()
{
// Trace.Write( m_guid, m_idStr );
}

}
private void RunBtn_Click(object sender, System.EventArgs e)
{
ResultEd.Text = "";
try
{

for( int i = 0; i < int.Parse( NumberEd.Text ); ++i )
{

Hashtable table = new Hashtable( 100 );
ArrayList ids = new ArrayList( 10 );
for( int j = 0; j < 10; ++j )
{
Guid id = Guid.NewGuid();
table[ id ] = null;
ids.Add( id );
}
for( int k=0; k < 10; ++k )
{
foreach( Guid id in ids )
{
table[ id ] = new CMyClass( 10 );
}

CMyClass myobj;
foreach( Guid id in ids )
{
myobj = (CMyClass) table[ id ];
myobj.id.ToString();
}
} // for k
} // for
}
catch( Exception ex )
{
ResultEd.Text = ex.Message + "...CallSTack:" +
ex.StackTrace;
}

GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();

GC.WaitForPendingFinalizers();
GC.Collect();

ResultEd.Text = "Done";
}

推荐答案

Zeng写道:
Zeng wrote:
终结者我的CMyClass在演示这个问题方面有很大的不同,没有它的问题没有问题不存在。
the finalizaer the my
CMyClass makes a big difference in demonstrating this issue, w/o it the
problem doesn''t exist.




实际上,终结器就是问题所在。当GC检测到带有终结器的

对象是垃圾时,它会复活。然后将它放在

一个终结队列中,由后台线程完成。当

终结线程实际调用finalize并从队列中删除你的

对象时,该对象再次可用于收集。

Of当然,它(可能)现在被撞了一代,所以

会坚持一段时间。


// Jon,谁'今天拖延了一下......


-

www.midnightbeach.com




" Zeng" <泽****** @ hotmail.com>在消息中写道

新闻:%2 **************** @ TK2MSFTNGP09.phx.gbl ...

"Zeng" <Ze******@hotmail.com> wrote in message
news:%2****************@TK2MSFTNGP09.phx.gbl...
我的CMyClass对象在每次运行此功能后都通过显示的简单网页得到了支持NumberEd编辑框。我的记忆资料显示,这些实例可以在3轮GC收集中存活 - 这不是我预期的。在我的真实代码中,CMyClass占用了大量的内存,而且他们都分享了另一个我没有足够记忆的课程的姿态
而不仅仅是一些记忆。请注意,我的
CMyClass终结者在演示此问题方面有很大的不同,因为它不存在问题。

I finally narrowed down my code to this situation, quite a few (not all)
of
my CMyClass objects got hold up after each run of this function via the
simple webpage that shows NumberEd editbox. My memory profile shows that
those instances survive 3 rounds of GC collections - it''s not what I
expected. In my real code, CMyClass occupies big amount of memory and
they
all share one stance of another class that I don''t have enough memory hold
more than a just a few in the memory. Notice that the finalizaer the my
CMyClass makes a big difference in demonstrating this issue, w/o it the
problem doesn''t exist.




为什么你有一个终结者,有终结者的课程

需要至少两次扫描才能收集。


Willy。



Why do you have a finalizer in the first place, classes having finalizers
need at least two sweeps to be collected.

Willy.





" Willy Denoyette [MVP]"写道:


"Willy Denoyette [MVP]" wrote:
为什么你有一个终结器,有终结器的类需要至少两次扫描才能收集。
Why do you have a finalizer in the first place, classes having finalizers
need at least two sweeps to be collected.




当涉及非托管资源时,IMO是CYA的主要原因。

的意图应该始终是尽快使用Dispose来清理它们,但是如果你忘记了,或者那个人必须维护你的代码一年之后离开

并没有意识到他需要,最终确定它最终会被清理好




The main reason IMO is CYA when unmanaged resources are involved. The
intent should always be to use Dispose to clean them up asap but if you
forget, or the person who has to maintain your code a year after you''ve left
doesn''t realize he needs to, finalize will make sure it''s cleaned up
eventually.


这篇关于不是内存泄漏,但可能是坏事的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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