עבור לתוכן

Destractor וניהול זיכרון בC#

Featured Replies

פורסם

קראתי שהGC יוצר תור של מצביעים לכל האובייקטים שיש להם Dtor ובזמן הביצוע של GC הוא מעביר אותם לתור נוסף.

אחרי שהוא מסיים את העבודה ומשחרר את כל הthreads הוא עובר על התור הזה בthread אחר ומפעיל את כל הפונקציות ההורסות.

1)האובייקט שיש לו Dtor עובר לדור 1 לא?

2)מתי משמידים את האובייקט? האם הDtor עושה את זה בלי קשר לקוד שכתבנו בתוכו?

פורסם

1)אוביקטים עוברים דור כאשר הם "שורדים" הרצה של GC,בלי קשר ל dtor

2)אוביקט משוחרר מהזיכרון כאשר הGC רץ ומוצא שלאוביקט הנ"ל אין שום רפרנס בתוכנית

תוסיף dtor לאוביקט שלך רק אם אין שום ברירה אחרת,ברוב המקרים זה גם לא נחוץ,וגם סתם מכביד על הGC

פורסם
  • מחבר

1)אוביקטים עוברים דור כאשר הם "שורדים" הרצה של GC,בלי קשר ל dtor

2)אוביקט משוחרר מהזיכרון כאשר הGC רץ ומוצא שלאוביקט הנ"ל אין שום רפרנס בתוכנית

תוסיף dtor לאוביקט שלך רק אם אין שום ברירה אחרת,ברוב המקרים זה גם לא נחוץ,וגם סתם מכביד על הGC

אתה סתם מדבר בכלליות.

תאמין לי שאני יודע את כל מה שאמרת.

כדי להפעיל את הdtor האובייקט צריך להיות "בחיים" מה שאומר שהוא צריך לשרוד את הניקוי של GC ולעבור דור. לא?

אחרי שהפעלת את הdtor מתי בדיוק תשמיד את האובייקט? הGC כבר סיים את הניקוי ושחרר את הthreads. האם הdtor משמיד את האובייקט והקוד שרשמת בתוכו מופעל שניה לפני שזה קורה?

פורסם

לא אתה קורא לdtor,אלא הGC.

לאחרי שהdtor רץ,GC ישחרר את האוביקט מן הזיכרון.

ב.net לא אתה אחראי לשחרור זיכרון (אלא בסיטואציות marshaling מסוימות),סביבת העבודה עושה את זה בשבילך.

פורסם
  • מחבר

אני יודע, אני שואל לידע כללי.

אוקיי מניסוי שערכתי עכשיו אפשר לראות שהאובייקט אכן עובר דור ושהdtor משמיד אותו.



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Memory
{
class point
{
private int x;

public point(int x)
{
this.x = x;
Console.WriteLine("in constractor");
}

~point()
{
Console.WriteLine("in destractor");
Console.WriteLine(GC.GetGeneration(this));
}
}

class Program
{
static void Main(string[] args)
{
point p = new point(32);
WeakReference t = new WeakReference(p);
Console.WriteLine(GC.GetGeneration(t));
p = null;
GC.Collect();
try
{
GC.GetGeneration(t);
}
catch
{
Console.WriteLine("the object is dead");
}
}
}
}

עכשיו כמה שאלות:

כשהGC משמיד את האובייקט הוא למעשה מפעיל את הפונקציה Finalize שמוגדרת בכל אובייקט והיא משמידה אותו נכון?

והdtor הוא בעצם override לפונקציה Finalize נכון? בגלל זה הוא משמיד את האובייקט למרות שהGC כבר סיים לנקות ושחרר את הthreads?

פורסם

מהידע המצומצם שלי על מימוש של GC בJAVA, אני יודע שהGC קורא לפונקציה Finalize בסוף החיים של העצם (כשהוא בא "לחסל אותו"), ולכן אתה יכול (לפחות ב JAVA, אני לא יודע מה עם #C) לדרוס (override) את הפונקציה Finalize, ולהריץ קוד מסוים בסוף החיים של העצם.

אני יודע שלפחות בJAVA, לא תמיד ה GC מבצע קריאה ל Finalize, ולכן יש פקודה שמפעילה את כל פונקציות ה Finalize של עצמים שמיועדים להריסה, אבל גם היא בעצמה לא בטוחה מדי.

מקווה שעזרתי במשהו... :s05:

פורסם

ממה שאני יודע ב#C הdtor קשור באופן הדוק ביותר לפונקצית dispose ו finalize כך שאם אתה רוצה לקרוא באופן יזום לניקוי האוביקט

בדרך כלל קוראים לdispose, ניראה לי שגם השמה של null גורם לריצה של finalize או dispose

הGC קורא לfinalize לפחות זה מה שרשום כאשר רוצים לישם את dispose

http://msdn.microsoft.com/en-us/library/system.idisposable.dispose(VS.71).aspx

פורסם

ממה שאני יודע ב#C הdtor קשור באופן הדוק ביותר לפונקצית dispose ו finalize כך שאם אתה רוצה לקרוא באופן יזום לניקוי האוביקט

בדרך כלל קוראים לdispose, ניראה לי שגם השמה של null גורם לריצה של finalize או dispose

הGC קורא לfinalize לפחות זה מה שרשום כאשר רוצים לישם את dispose

http://msdn.microsoft.com/en-us/library/system.idisposable.dispose(VS.71).aspx

dtor=finializer בדוטנט,והוא נקרא אך ורק על ידי הGC כאשר הוא עובר על תור הfinalizers

dispose מצד שני,היא מתודה שהלקוח יכול לקרוא לה וליזום שחרור של resources (מדובר על unmanaged resources שחובה לשחרר בעצמך,כל שאר המשאבים מטופלים לבד יפה מאוד על ידי הGC)

השמה לnull מורידה את הreference count של האוביקט ב1. רק כאשר הGC רץ,ורק כאשר לאוביקט אין רפרנסים בכלל בתוכנית הGC ינקה אותו (ויקרא לfinializer AKA dtor שלו בשלב כזה או אחר). שים לב,כאשר אתה יוצא מסקופ אז הרפרנס יורד אוטומטית,אז אין שום טעם לשנות רפרנס לnull (יש לזה כמה שימושים דווקא,בעיקר עם weak references,אבל אני מעדיף לא להכנס לזה כרגע)

לסיכום:

dtor = finalizer,נקרא על ידי הGC מתישהו אחרי שהאוביקט שוחרר מהזיכרון. חשוב להזכיר,הGC לא רץ תמיד,אז אין לסמוך אף פעם על תזמונים שלו בכל מה שקשור לקריאה לfinalizer

dispose = מתודה שהלקוח של המחלקה קורא לה,(ולפי דיזיין לפחות) משחררת משאבים unmanaged שהאוביקט משתמש בהם.

מקווה שהנושא הובהר

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

דיונים חדשים