质疑CLR Via C#中的一段代码,求指教狠批,只要能求得答案!解决方案
质疑CLR Via C#中的一段代码,求指教狠批,只要能求得答案!!
这个问题困扰了大半个月了,睡觉之前老在琢磨!憋不住了来CSDN求解释!大恩不言谢!
代码是该书第三版 泛型部分P244
我要质疑的部分是【】包围的代码(其他部分代码我很清楚其目的),我认为这部分代码从【理论上】可以删除,我的理由是:
挂起当前线程,直到处理终结器队列的线程清空该队列为止。( MSDN的释义)
挂起当前线程是应用程序的线程,处理终结器队列(也即Freachable队列)的线程是CLR专配线程,具有高优先级和特殊待遇,当freachable队列被清空时,会完成对每个对象的Finalize调用,这样对象才成为真正的垃圾。
具备Finalize方法的对象至少需要两次GC(排除代的提升作用),所以后面又加了句GC.Collect(),手动回收那些已经终结的对象的内存。
WaitForPendingFinalizers调用时,会使得应用程序的所有线程挂起睡眠直到所有Finalize方法调用完毕。
那些具备Finalize方法的对象才真正成为垃圾,所以问题来了,这个方法明显是针对处理终结器队列操作的,也就是那些具备Finalize方法的对象,但在这段代码中所有对象都没有析构函数,为何需要调用该方法?!?
------解决方案--------------------
sample just sample...有时候例子就是给人看看怎么写而已,未必有意义...所以,莫钻牛角尖...
ps:我没看过这书,你摘得这段又缺少上下文,说实在的我也不知道它要干什么...你等大侠出现吧...
------解决方案--------------------
恩,值得深思
------解决方案--------------------
这个问题困扰了大半个月了,睡觉之前老在琢磨!憋不住了来CSDN求解释!大恩不言谢!
代码是该书第三版 泛型部分P244
- C# code
using System; using System.Collections.Generic; using System.Diagnostics; using System.Collections; namespace GenericsTest { sealed class Program { static void Main(string[] args) { ValueTypePerfTest(); ReferenceTypePerfTest(); Console.ReadKey(); } private static void ValueTypePerfTest() { const int count = 10000000; using (new OperationTimer("List<Int32>")) { List<Int32> l = new List<int>(count); for (Int32 n = 0; n < count; n++) { l.Add(n); Int32 x = l[n]; } l = null; } using (new OperationTimer("ArrayList of Int32")) { ArrayList a = new ArrayList(); for (Int32 n = 0; n < count; n++) { a.Add(n); Int32 x = (Int32)a[n]; } a = null; } } private static void ReferenceTypePerfTest() { const int count = 10000000; using (new OperationTimer("List<String>")) { List<string> l = new List<string>(); for (Int32 i = 0; i < count; i++) { l.Add("X"); String x = (String)l[i]; } l = null; } using (new OperationTimer("ArrayList Of String")) { ArrayList a = new ArrayList(); for (Int32 i = 0; i < count; i++) { a.Add("X"); String x = (String)a[i]; } a = null; } } } internal sealed class OperationTimer : IDisposable { public void Dispose() { Console.WriteLine("{0:###0.00000000} 秒, (GCS={1}) {2}", (Stopwatch.GetTimestamp() - m_startTime) / (double)Stopwatch.Frequency, GC.CollectionCount(0) - m_collectionCount, m_text); } private Int64 m_startTime; private String m_text; private Int32 m_collectionCount; public OperationTimer(String text) { PrepareForOperation(); m_text = text; m_collectionCount = GC.CollectionCount(0); m_startTime = Stopwatch.GetTimestamp(); } private static void PrepareForOperation() { GC.Collect(); 【 GC.WaitForPendingFinalizers(); GC.Collect();】 } } }
我要质疑的部分是【】包围的代码(其他部分代码我很清楚其目的),我认为这部分代码从【理论上】可以删除,我的理由是:
- C# code
GC.WaitForPendingFinalizers();
挂起当前线程,直到处理终结器队列的线程清空该队列为止。( MSDN的释义)
挂起当前线程是应用程序的线程,处理终结器队列(也即Freachable队列)的线程是CLR专配线程,具有高优先级和特殊待遇,当freachable队列被清空时,会完成对每个对象的Finalize调用,这样对象才成为真正的垃圾。
具备Finalize方法的对象至少需要两次GC(排除代的提升作用),所以后面又加了句GC.Collect(),手动回收那些已经终结的对象的内存。
WaitForPendingFinalizers调用时,会使得应用程序的所有线程挂起睡眠直到所有Finalize方法调用完毕。
那些具备Finalize方法的对象才真正成为垃圾,所以问题来了,这个方法明显是针对处理终结器队列操作的,也就是那些具备Finalize方法的对象,但在这段代码中所有对象都没有析构函数,为何需要调用该方法?!?
------解决方案--------------------
sample just sample...有时候例子就是给人看看怎么写而已,未必有意义...所以,莫钻牛角尖...
ps:我没看过这书,你摘得这段又缺少上下文,说实在的我也不知道它要干什么...你等大侠出现吧...
------解决方案--------------------
恩,值得深思
------解决方案--------------------