XSLT存档  

不及格的程序员-八神

 查看分类:  ASP.NET XML/XSLT JavaScripT   我的MSN空间Blog

今天看到一个老外,用C#代码讲 WeakReferences的用法
不过我发现它的例子应该是用毛病的,在它的例子中weakRef应该没有逃开作用域,不能被正确回收,所以例子的结果也是不准的

末尾给出了我对其修改后的例子,给出了两种作用域的对比

Deciding When to Use Weak References in .NET

 
 

.NET WeakReference Example

The .NET WeakReference Class represents a weak reference, which references an object while still allowing that object to be reclaimed by garbage collection. Now, let’s see an example. Create a console application from Visual Studio and name it MyWeakReference.

Create a WeakReference object and pass an object reference to the constructor call. In the following example, I have used the StringBuilder object.

static WeakReference myweakerenceobject;
myweakerenceobject = new WeakReference(new StringBuilder("My weak
   reference object."));

During execution, in the middle of the program, the garbage collector is executed by using GC.Collect. After this call, the object pointed to by the WeakReference no longer exists. After the call, I have checked if the object is still alive. Refer to the following code snippet.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyWeakReference
{
   class Program
   {
      static WeakReference myweakerenceobject;
      static void Main(string[] args)
      {
         myweakerenceobject = new WeakReference(new
            StringBuilder("My weak reference object."));
         if (myweakerenceobject.IsAlive)
         {
            Console.WriteLine((myweakerenceobject.Target as
               StringBuilder).ToString());
         }
         GC.Collect();
         // Check if still alive after GC call.
         if (myweakerenceobject.IsAlive)
         {
            Console.WriteLine("Object Alive");
         }
         Console.WriteLine("[I'm Done]");
         Console.Read();
      }
   }
}

The IsAlive property mentioned in the preceding code is an important property on the WeakReference type. This Boolean property indicates whether or not the object pointed to by the WeakReference has been collected.

I have also used the Target property in the code snippet. That returns an object that contains the reference to the instance I stored in the WeakReference. However, if the original object has already been garbage collected, the Target property will be null and then you can no longer reference the original object.

What Are the Differences Between Weak and Strong References?

The difference between a weak and a strong reference to an object is that, while the former still allows the garbage collector to reclaim the memory occupied by that object, a strong reference to an object doesn’t allow the garbage collector to reclaim the memory occupied by that object if the object is reachable.

Should We Use WeakReference?

A developer should use long weak references only when necessary because the object is unpredictable after finalization. We should avoid using weak references to small objects because the pointer itself may be as large or larger. Instead of weak references, we should develop an effective caching policy in an application.

WeakReference is often used for implementing Weak Events. Event handlers are a frequent cause of memory leaks, particularly when you have a long-lived service with events that multiple instances subscribe to.

Conclusion

That’s all for today. The following references are for for further study.

 

下面是我更改后的例子,可以看到,弱引用的target值已经不在被回收了


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MyWeakReference
{
    class Program
    {
        ~Program()
        {
            Console.WriteLine("finalizer.");
        }
        
        static void Main(string[] args)
        {
            testStub();
            new Program().test(" normalMethod");
            GC.Collect();
            // Check if still alive after GC call.

            Console.WriteLine("[I'm Done]");
            Console.ReadKey();
        }

        static void testStub()
        {
            new Program().test(" static");
        }

        void test(string strFlag)
        {
            var str = new StringBuilder("My weak reference object.");
            WeakReference myweakerenceobject = new WeakReference(str, false);
            if (myweakerenceobject.IsAlive)
            {
                Console.WriteLine((myweakerenceobject.Target as
                   StringBuilder).ToString());
            }
            new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(delegate (object arg)
            {
                System.Threading.Thread.Sleep(2000);
                object[] weakArray = (arg as object[]);
                int iIndex = 0;
                foreach (WeakReference item in weakArray)
                {
                    if (item.IsAlive)
                    {
                        Console.WriteLine(
                            string.Format("iIndex:" + iIndex.ToString() + " Object Alive, value:{0}, flag:{1}", item.Target,  (weakArray[2] as WeakReference).Target
                            ));
                    }
                    else
                    {
                        Console.WriteLine("iIndex:" + iIndex.ToString() +" Object noAlive, flag:" + (weakArray[2] as WeakReference).Target);
                    }
                    iIndex++;
                }
                Console.WriteLine();
            })).Start(new object[] { new WeakReference(this), myweakerenceobject , new WeakReference(strFlag)});
            //str = null;
            //myweakerenceobject = null;
        }
    }
}

 

posted on 2023-06-16 14:21  不及格的程序员-八神  阅读(5)  评论(0编辑  收藏  举报