Kiedy obiekt zostanie usunięty ?

0
class A {...}

class Foo {

   private A a;

   public Foo(A a)
   {
       this.a=a;
   }

}

public class Hello1
{
   public static SA;

   public static Init()
   {
      SA = new A();
      Foo BAR = new Foo(SA);
   }

   public static void Main()
   {
      Init();
   }
}

Mam kod analogiczny do powyższego. Obiekt pod referencją BAR, mimo wyjścia z funkcji Init(), nadal istnieje i funkcjonuje - dlaczego tak ? Z powodu, że do obiektu SA nadal istnieje statyczna referencja?

0

kilka pytać dla jasności:

  • w jaki sposób sprawdzasz że obiekt BAR dalej istnieje?
  • czy zmienna statyczna Hello1.SA to klasa A czy zmienna var?
1

Obiekty usuwane są wtedy kiedy GC uzna to za stosowne. Nie są usuwane pojedynczo, bo jest to zwyczajnie nieopłacalne.

Odpowiadając na pytanie: "Kiedy obiekt zostanie usunięty?" odpowiedzieć należy, że nie wiadomo, ponieważ programista nie posiada nad tym kontroli. Nawet obiekt, który nie posiada "aktywnych" referencji może zostać usunięty dopiero x-czasu później, a nie w momencie utraty tej ostatniej referencji do siebie. Zakres { } również nie jest tutaj żadnym wyznacznikiem.

0

Tak to pole statyczne klasy A.

Rozumiem, zasadę działania GC, że odpala się kiedy chce (ma zestaw reguł), jednak gdy do obiektu nie ma referencji to jednak kiedyś zostanie tam usunięty. Ja z kolei znalazłem taki kwiatek, jak podałem, obiekt klasy A, jest systemowym watcherem na katalog i teraz mimo, wyjścia z metody inicjalizacyjnej obiekt, klasy Foo, żyje, a obiekt SA wyzwala w nim pewne metody (przez eventy) i te metody działają ... Ale doszedłem do tego dlaczego chyba - wynika to z faktu, że metody tej klasy używają jedynie parametrów, stałych i zmiennych globalnych systemu, nie używają natomiast nic z pól obiekty, więc podejrzewam, że obiekt klasy Foo jest usunięty, jednak obiekt SA wyzwala same metody, które nie są dowiązane do obiektu - przynajmniej w C++ da się wywołać metodę klasy bez powoływania jej obiektu. Ktoś tutaj zrobił sobie chyba pseudo singleton, wiec przerobię to na prawdziwy singleton, ale powiedzcie, czy taka sytuacja może mieć miejsce ??

Dla jasności stawiam hipotezę:

"Obiekt klasy Foo zarejestrowała obiektowi SA swoją metodę jako event, po wyjściu z metody Inicjalizacyjnej GC usunął obiekt klasy Foo, ale SA wywołuje nadal metody Foo, gdyż nie zależą od żadnych niestatycznych pól tejże klasy"

1

ojej, i wszystko stało się jasne po Twoim ostatnim poście -> nie rozumiesz jak działają delegaty,
skoro przypisujesz event, to oprócz wskaźnika na metodę również jest trzymana referencja do obiektu na którym tą metodę wywołać,
Foo jest ciągle żywe, i GC go nie usunie dopóki nie odepniesz metody z eventu zarejestrowanego w statycznym polu SA

0

To nie mój kod, tylko napotkałem go podczas prac, ale masz racje - nie widziałem, że delegat prócz wskaźnika przechowuje referencje z kontekstem obiektu, dzięki za pomoc w zrozumieniu. Natomiast, czy uważasz, to za dobrą praktykę ( takie przypinanie lokalnych obiektów do eventów)? Mi się wydaje, że to strasznie zaciemnia kod.

0
Pijany Samiec napisał(a):

To nie mój kod, tylko napotkałem go podczas prac, ale masz racje - nie widziałem, że delegat prócz wskaźnika przechowuje referencje z kontekstem obiektu, dzięki za pomoc w zrozumieniu.

A na co ten "wskaźnik" by wskazywał, gdyby nie miał referencji do obiektu?

Natomiast, czy uważasz, to za dobrą praktykę ( takie przypinanie lokalnych obiektów do eventów)? Mi się wydaje, że to strasznie zaciemnia kod.

Generalnie eventy "zaciemniają" kod i w ogóle wszystko, co nie jest procedurą wykonywaną linijka po linijce jest zaciemnione.
Masz pomysł jak to inaczej rozwiązać?

0

A jak GC sprawdza czy do danego obiektu nie ma już referencji ?

0

Istnieją odpowiednie algorytmy - poczytaj np. o mark and sweep.
Generalnie how garbage collector works w Google :-)

0

W skrócie, próbuje dojść do obiektu począwszy od "korzeni". Korzeniami są parametry metod, zmienne lokalne i pola statyczne.

0
somekind napisał(a):
Pijany Samiec napisał(a):

To nie mój kod, tylko napotkałem go podczas prac, ale masz racje - nie widziałem, że delegat prócz wskaźnika przechowuje referencje z kontekstem obiektu, dzięki za pomoc w zrozumieniu.

A na co ten "wskaźnik" by wskazywał, gdyby nie miał referencji do obiektu?

Na metodę, tj wskaźnik na funkcję. Spaczenie z C++ gdzie można wywołać metodę w klasie bez powołyania obiektu.

Natomiast, czy uważasz, to za dobrą praktykę ( takie przypinanie lokalnych obiektów do eventów)? Mi się wydaje, że to strasznie zaciemnia kod.

Generalnie eventy "zaciemniają" kod i w ogóle wszystko, co nie jest procedurą wykonywaną linijka po linijce jest zaciemnione.
Masz pomysł jak to inaczej rozwiązać?

W taki sposób? Pozwoli to nie zastanawiać się osobą które nie wiedzą wszystkiego, co się dzieje, z obiektem, że nadal żyje. Od razu widać, że żyje, bo jest ustawiona do niego referencja w sposób bezpośredni.

class A {...}
 
class Foo {
 
   private A a;
 
   public Foo(A a)
   {
       this.a=a;
   }
 
}
 
public class Hello1
{
   public static A SA;
   
   public static Foo BAR;
 
   public static Init()
   {
      SA = new A();
      BAR = new Foo(SA);
   }
 
   public static void Main()
   {
      Init();
   }
}

W zasadzie, jeżeli BAR faktycznie jest tworzony i potem tylko eventy do niego wołają, to można by z niego też singletona zrobić.

1 użytkowników online, w tym zalogowanych: 0, gości: 1