Information Technology Center
أهلا ومرحبا بسيادتكم في منتدانا ومنتداكم منتدي مركز تقنية المعلومات نرجو ان تستفيدوا وأن تكون بداية لإنضمامكم لنا و عسي أن تسفيدوا بما لدينا وتفيدونا بما لديكم

Information Technology Center

منتدي مركز تقنية المعلومات (كل ما يخص التكنولوجيا والكمبيوتر)
 
الرئيسيةبوابه المنتدياليوميةس .و .جبحـثالأعضاءالمجموعاتالتسجيلدخول
بحـث
 
 

نتائج البحث
 
Rechercher بحث متقدم
مواضيع مماثلة
    المواضيع الأخيرة
    » احسن تعليم موجود علي النت لبرنامج Autidesk 3d max 2011
    الأحد مايو 03, 2015 11:15 pm من طرف abdulrhmsn.salam

    » برنامج الأذان لجوال نوكيا الجيل الخامس
    الخميس أكتوبر 11, 2012 11:15 am من طرف nadia8077

    » حل مشاكل المزرعة السعيدة ... هكر بالشرح الكامل
    السبت يونيو 09, 2012 3:57 pm من طرف Master_Mido

    » دورة كاملة من أقوي الشركات الرائده في التعليم في Adobe fireworks
    الجمعة أكتوبر 21, 2011 5:08 pm من طرف Master_Mido

    » برنامج بالتوك جنان
    الإثنين أغسطس 22, 2011 11:52 pm من طرف Master_Mido

    » برنامج ريل بلير مسلي جدا
    الإثنين أغسطس 22, 2011 11:51 pm من طرف Master_Mido

    » برنامج الاذان للكمبيوتر هايل
    الأحد يوليو 31, 2011 10:49 pm من طرف Master_Mido

    » برنامج تحميل افلام من النت جوهري
    الأحد يوليو 31, 2011 10:48 pm من طرف Master_Mido

    » أقوي اسطوانة صيانة في التاريخ
    الإثنين يوليو 18, 2011 6:01 pm من طرف Master_Mido

    تسجيل صفحاتك المفضلة في مواقع خارجية
    تسجيل صفحاتك المفضلة في مواقع خارجية Digg  تسجيل صفحاتك المفضلة في مواقع خارجية Delicious  تسجيل صفحاتك المفضلة في مواقع خارجية Reddit  تسجيل صفحاتك المفضلة في مواقع خارجية Stumbleupon  تسجيل صفحاتك المفضلة في مواقع خارجية Slashdot  تسجيل صفحاتك المفضلة في مواقع خارجية Yahoo  تسجيل صفحاتك المفضلة في مواقع خارجية Google  تسجيل صفحاتك المفضلة في مواقع خارجية Blinklist  تسجيل صفحاتك المفضلة في مواقع خارجية Blogmarks  تسجيل صفحاتك المفضلة في مواقع خارجية Technorati  

    قم بحفض و مشاطرة الرابط Information Technology Center على موقع حفض الصفحات

    قم بحفض و مشاطرة الرابط Information Technology Center على موقع حفض الصفحات
    سحابة الكلمات الدلالية
    سؤال و جواب في الاسلام
    Viewers

    شاطر | 
     

     MultiCast Delegates & Memory Leaks

    استعرض الموضوع السابق استعرض الموضوع التالي اذهب الى الأسفل 
    كاتب الموضوعرسالة
    TheManager
    نائب رئيس مجلس الإدارة
    نائب رئيس مجلس الإدارة
    avatar

    عدد المساهمات : 25
    نقاط : 56885
    السٌّمعَة : 0
    تاريخ التسجيل : 25/05/2010
    العمر : 34
    الموقع : eng.freevar.com

    بطاقة الشخصية
    صنع في :.....:
    المود ايه (توداي): عايش وخلاص

    مُساهمةموضوع: MultiCast Delegates & Memory Leaks   الثلاثاء مايو 25, 2010 7:32 pm

    مقال تقني: Memory Leaks In .NET
    بيئة التطوير : جميع إصدارات الفيجوال ستوديو بدءًا من 2003
    اللغة #C نفس ما سيرد في هذا الموضوع ينطبق على VB .
    المستوى: متقدم (يفترض بقارء الموضوع أن يكون ملماً باساسيات الدوت نت ).

    في اللغات الغير مدارة مثل C++ عليك أن تتذكر دائماً بأنه يجب عليك أن تتخلص من الذاكرة التي قمت بتخصيصها من أجل كائن معين عندما تصبح بدون حاجة إليه, وإلا فسيحدث ما يسمى بال Memory Leak أو تسرب الذاكرة , في عالم الدوت نت والمصادر المدارة, إمكانية حدوث ال Memory Leak شبه منعدمة في أغلب الأحيان , والفضل يعود إلى ال CLR وآلية إدارة الذاكرة التي يعتمدها من خلال ال Garbage Collection , ما يعني أن اي كائن يتم تخصيص مساحة من الذاكرة له يتم نحريرها فور انتهاء مدة حياة ذلك الكائن وحالما يصبح بدون أي References .لكن ما يحدث في التطبيقات التي تعمل باستمرار وحيث أن حجم الذاكرة المستهلكة يزداد كلما زادت فترة حياة ذلك التطبيق , فإنه من الممكن حدوث ال Memory Leaks . تحدث مشاكل الذاكرة هذه عادة بسبب الكائنات التي تبقى عالقة في الذاكرة من دون استخدامها داخل تطبيقك , مثال شائع عن مسببات ال Memory Leaks وهي ال MulticastDelegates وبالضبط ال EventHandlers فمثلا عندما تقوم بربط EventHndler من كائن A إلى EventHandler لكائن B ولم تقم بفصل هذا الارتباط فسيبقى الكائن B عالقاً في الذاكرة ولن تقوم GC بجمعه حتى عندما تسند القيمة null أو Nothing له لأنه لازال هناك مرجع من الكائن A يشير إلى الكائن B , والمثال التالي يوضح ذلك:
    رمز:
    public class Server
    {
    public EventHandler handler;
    }


    public class Client
    {
    Server _server = null;



    public Client(Server server)
    {
    this._server = server;
    this._server.handler += new EventHandler(Handle);
    }


    private void Handle(object sender, EventArgs e)
    {
    // Do something
    }
    }




    لنفترض بعد ذلك أنك قمت بإنشاء 2000 نسخة Instance من الفئة Client :
    رمز:
    class Test
    {
    Server server = new Server();
    public Test()
    {
    for (int i = 0; i < 2000; i++)
    {
    var client = new Client(this.server);

    }



    }
    }



    }

    قد يخطر في بالك أنه بعد الانتهاء من استخدام ال 2000 كائن سيتم تدميرهم وتحرير الذاكرة التي كانو يشغلونها وهذا خاطئ , سيبقى الألفين كائن معلقين في الذاكرة والسبب ان كل منهم لا يزال يرتبط بالكائن server الخاص بالفئة Test عن طريق ال EventHandler حيث قمنا بإنشاء هذا الارتباط داخل الConstructor الخاص بالفئة Client ولكنا لم نقم بالتخلص من هذا الارتباط وذلك بعمل Unsubscribing لل Eventhandlers, وفي العادة يتم فصل هذا الارتباط عن طريق تحقيق الواجهة IDisposable للفئة Client ويكون ذلك داخل الإجراء Dispose كما هو موضح في الكود التالي:
    رمز:
    public class Client : IDisposable
    {
    Server _server = null;
    bool disposed = false;


    public Client(Server server)
    {
    this._server = server;

    this._server.handler += new EventHandler(Handle);
    }



    private void Handle(object sender, EventArgs e)
    {
    if (disposed) throw new ObjectDisposedException("client");
    // Do something
    }


    public void Dispose()
    {
    this._server.handler -= new EventHandler(Handle);
    this.disposed = true;
    }
    }




    الآن وباستخدام using Statement أو استدعاء الإجراء Dispose يمكنك التأكد من أنه سيتم فصل الارتباط وتحرير ال 2000 كائن في المرة التالية التي يتم فيها عمل Garbage Collecting للذاكرة بعد الانتهاء من ال using Block كما يوضح المثال التالي:
    رمز:
    class Test
    {
    Server server = new Server();
    public Test()
    {
    for (int i = 0; i < 2000; i++)
    {
    using (var client = new Client(this.server))

    {
    // Do something...
    }
    }



    }
    }


    وبالرغم من ذلك فإن هذا الحل لن يكون الأفضل فقد تضطر لعدم استخدام الواجهة Idisposable عندها لابد من استخدام الفئة
    [size=12]المؤقتات Timers

    يمكن أيضًا للمؤقتات المتوفرة قي الدوت نت أن تتسبب في تسرب الذاكرة , وهناك حالتان مختلفتان حسب نوع المؤقت الذي نتعامل معه , لنلق نظرة على الفئة Timer الموجودة ضمن مجال الأسماء System.Timers , بالنظر إلى المثال التالي فإنه عند إنشاء نسخة منها سيتم استدعاء الإجراء Timer_Tick كل ثانية:

    رمز:
    class TimerTest
    {
    Timer timer = new Timer { Interval = 1000};


    private TimerTest()
    {
    this.timer.Elapsed += Timer_Tick;
    this.timer.Start();



    }

    private void Timer_Tick(object sender, ElapsedEventArgs e)
    {
    Console.WriteLine("Tick!");
    }
    }


    ولسوء الحظ , فإن هذا الكائن سيبقى عالق إلى حتى ينتهي التطبيق ولن تتمكن GC من التقاطه والسبب أن الدوت نت نفسه يحتفظ بمرجع إلى جميع المؤقتات النشطة من النوع System.Timers.Timer من جهة , ومن جهة أخرى فإن كائن Timer نفسه مرتبط مع EventHandler الخاص بفئتك , وفي هذه الحالة لن يفيدك القيام ب Unsubscribing لل EventHandler وحده, بل عليك أيضًا استخدام الواجهة IDisposable واستدعاء الإجراء Dispose الخاص بالفئة Timer داخل الإجراء Dispose الخاص بفئتك. كما هو موضح في الكود التالي:
    رمز:
    class TimerTest : IDisposable
    {
    Timer timer = new Timer { Interval = 1000};
    bool disposed = false;
    private TimerTest()

    {
    this.timer.Elapsed += Timer_Tick;
    this.timer.Start();



    }

    private void Timer_Tick(object sender, ElapsedEventArgs e)
    {
    if (disposed) throw new ObjectDisposedException(GetType().FullName);
    Console.WriteLine("Tick!");
    }


    public void Dispose()
    {
    timer.Dispose();
    timer.Elapsed -= Timer_Tick;
    this.disposed = true;
    }
    }


    نفس الكلام السابق ينطبق على الفئة System.Windows.Forms.Timer .
    الأمر مختلف بالنسبة للفئة System.Threading.Timer , فهو من نوع خاص, فالدوت نت لا تحتفظ بأي مراجع نحو المؤقتات النشطة من هذا النوع , ولكنها تحتفظ بال Callback Delegate الذي يتم تمريره لل Constructor وهذا يعني أنك إذا نسيت استدعاء الإجراء Dispose الخاص بالفئة Timer فسيتم ستدعاء ال Fimalizer الخاص بها في أي لحظة ما يعني احتمال حدوث خطأ غير متوقع في سير عمل برنامجك بعد تدمير ال Timer , جرب المثال التالي في الوضع Release بدل الوضع Debug.
    رمز:
    Timer t = new Timer(delegate { Console.WriteLine("Tick"); }, null, 1000, 1000);
    GC.Collect();
    Thread.Sleep(10000);


    لاحظ أنه إذا قمت بتجربة الكود السابق فإن المؤقت لن يعمل ولو لمرة واحدة وسيتم عمل Finalizing له وجمعه عند استدعاء GC.Collect بشكل صريح. وحتى تتمكن من حل المشكلة لا بد من استخدام ال using Statement حتى تضمن أن GC لن يستطيع الوصول إلى المؤقت وجمعه. والاستدعاء الضمني للإجراء Dispose في نهاية ال using Block يضمن ذلك, ولكن استدعاء Dispose في هذه الحالة قد يطيل عمر المؤقت في الذاكرة!

    معالجة مشاكل ال Memory Leaks:

    أسهل طريقة يمكن من خلالها تجنب مشاكل تسرب الذاكرة من خلال قياس كمية الذاكرة المستهلكة طوال فترة كتابة البرنامج, يمكنك الحصول على قدر الذاكرة التي تستهلكها كائنات برنامجك باستخدام الإجراء GC.GetTotalMemory , حيث يمكن تمرير قيمة منطقية , فإن قمت بتمرير True فذلك سيجعل الGC تقوم بعمل Garbage Collecting أولاً:
    رمز:
    Console.WriteLine(GC.GetTotalMemory(true));

    إذا كنت تعمل على تطبيق تستخدم فيه Unit Tests يمكنك القيام بعمليات التحقق من أن الذاكرة يتم تحريرها كما هو متوقع وإذا فشل أي تحقق Assertion فعليك التحقق عندها فقط من التغييرات الأخيرة التي قمت بها في تطبيقك.

    إذا كنت تعمل على تطبيق ضخم وتعاني من مشكلة بسبب حدوث تسرب في الذاكرة , فقد تساعد الأداة windbg.exe على اكتشافها , هناك أيضأ بعض الأدوات التي تعتمد على واجهة رسومية تساعد على فهم مايحدث بالضبط مثل Microsoft CLR Profiler , و SciTech Memory Profiler , و RedGate ANTS Memory Profiler , وال CLR نفسه يحتوي على مجموعة من الأداوت المساعدة مثل WMI Counters التي تساعد على مراقبة الموارد Resources التي يستهلكها البرنامج.
    [/size]
    الرجوع الى أعلى الصفحة اذهب الى الأسفل
    معاينة صفحة البيانات الشخصي للعضو http://eng.freevar.com
    Master_Mido
    Administration
    Administration
    avatar

    عدد المساهمات : 443
    نقاط : 66090
    السٌّمعَة : 95
    تاريخ التسجيل : 25/04/2010
    العمر : 29
    الموقع : http://i-t-center.ahlamontada.com

    بطاقة الشخصية
    صنع في :.....: بلجاي
    المود ايه (توداي): عاشق ولهان

    مُساهمةموضوع: رد: MultiCast Delegates & Memory Leaks   الثلاثاء يونيو 01, 2010 4:06 am

    God Bless You On These Info

    _________________________________

    ما هو المستحيل ؟!







    "إن الله لا يغير ما بقوم حتي يغيروا ما بأنفسهم"

    راقب أفكارك لأنها ستصبح كلمات
    وراقب كلماتك لأنها ستصبح أفعال
    وراقب أفعالك لأنها ستصبح عادات
    وراقب عاداتك لأنها ستصبح شخصية
    وراقب شخصيتك لأنها ستحدد مصيرك
    الرجوع الى أعلى الصفحة اذهب الى الأسفل
    معاينة صفحة البيانات الشخصي للعضو http://i-t-center.ahlamontada.com
    TheManager
    نائب رئيس مجلس الإدارة
    نائب رئيس مجلس الإدارة
    avatar

    عدد المساهمات : 25
    نقاط : 56885
    السٌّمعَة : 0
    تاريخ التسجيل : 25/05/2010
    العمر : 34
    الموقع : eng.freevar.com

    بطاقة الشخصية
    صنع في :.....:
    المود ايه (توداي): عايش وخلاص

    مُساهمةموضوع: رد: MultiCast Delegates & Memory Leaks   الخميس يونيو 03, 2010 6:25 pm

    Many thanks 4 ur reply

    _________________________________
    [ندعوك للتسجيل في المنتدى أو التعريف بنفسك لمعاينة هذا الرابط]
    الرجوع الى أعلى الصفحة اذهب الى الأسفل
    معاينة صفحة البيانات الشخصي للعضو http://eng.freevar.com
     
    MultiCast Delegates & Memory Leaks
    استعرض الموضوع السابق استعرض الموضوع التالي الرجوع الى أعلى الصفحة 
    صفحة 1 من اصل 1
     مواضيع مماثلة
    -
    » طريقة زيادة مساحة الـ RAM دون الحاجة لتركيب RAM إضافية

    صلاحيات هذا المنتدى:لاتستطيع الرد على المواضيع في هذا المنتدى
    Information Technology Center :: القسم التكنولوجي :: البرمجة-
    انتقل الى: