2010-06-22 13 views
6

Jestem programistą Delphi i próbuję zrobić coś z C# tutaj. Czy interfejsy w C# działają w taki sam sposób, jak w Delphi - nie musisz martwić się o jego zwalnianie, ponieważ jest on wolny, gdy jest poza zakresem.Jaka jest różnica w używaniu pamięci (czyszczenie itd.) Interfejsu Delphi i interfejsów C#

+0

Ronaldo, czy konkretnie pytasz o interfejs, czy miałeś na myśli odniesienia? –

+0

Pytam o interfejsy - ze względu na sposób, w jaki obsługuje go Delphi, mam zamiar zbudować coś i chcę korzystać z interfejsu, ale brakuje mu wiedzy o tym, co dzieje się za sceną. – ronaldosantana

+0

Ta część powinna być teraz jasna (-: –

Odpowiedz

7

Tak, dla programisty wyglądają tak samo. Użyj i zapomnij.

Wewnętrznie działają inaczej, w .NET interfejs jest (tylko kolejnym) odniesieniem, które jest wymazywane przez Garbage collectora.

Interfejsy Delphi są szczególnym rodzajem odniesienia, które są liczone w odwołaniach (inna technika zarządzania Meory).

Główna różnica .NET/Delphi polega na tym, że w .NET wszystkie odwołania (interfejs, obiekt i tablica) to śmieci zebrane.

+1

Dziękuję za wyjaśnienie. Byłby to dobry punkt, aby powiedzieć, że jeśli sprawię, że mój obiekt zaimplementuję IDisposable i użyję czegoś takiego jak" using (MyClass myobj = new MyClass()) {} Mogłem osiągnąć coś podobnego do tego, co robi Delphi (poza zakresem, gotowe) zamiast czekać na odśmiecacz? – ronaldosantana

+0

@Ronaldo: Tak, nieco. Ale nie powinieneś normalnie tego robić. IDisposable służy do zarządzania zasobami (FileHandles), a nie pamięcią. Nie możesz kontrolować czasu życia obiektów, ale nie musisz się o to martwić. –

0

Wszystko w C# jest zbiorem śmieci, więc nie trzeba ich ręcznie odblokowywać.

Istnieją jednak znaczne różnice. Interfejsy Delphi są liczone odwołanie, C# interfejsy są zbierane śmieci. C# obsługuje dziedziczenie wielu interfejsów.

+1

Delphi obsługuje także dziedziczenie wielu interfejsów, nie ma tam różnic. –

+1

Z pewnością jest prawdą tylko, że zarówno C#, jak i Delphi obsługują implementacje wielu interfejsów *? "Dziedziczenie wielu interfejsów" może sugerować, że interfejs "A" może dziedziczyć z wielu interfejsów, "B" i "C", co jest * nie * możliwe w Delphi lub C#. Oczywiście, jeśli klasa implementuje wiele interfejsów, to każda klasa pochodna/potomna "dziedziczy" te wiele interfejsów , ale moim zdaniem jest to uboczny efekt uboczny posiadania dziedziczenia implementacji i możliwość implementowania wielu interfejsów i nie stanowi "funkcji" dziedziczenia z wieloma interfejsami: – Deltics

+0

@Deltics, patrz na początek: http: // stackoverflow. com/questions/2346210/ –

2

I nie sądzę, że jest wolny, gdy poza zakresem ale kiedy zbieranie śmieci dzieje (gdy nie są już używane)

+1

rzeczywiście poprawnie, ale trudne do rozszyfrowania: jakie zachowanie jest Delphi i co .NET? –

0

Zarządzanie pamięcią jest obsługiwane przez CLR. Wyrzucanie śmieci jest nieodłączną usługą w środowisku CLR.

Nie musisz usuwać zmiennych lub pól, aby obiekt został zebrany przez odśmiecanie.

Nie musisz wdrażać ani używać IDisposable do czyszczenia pamięci. Metoda Dispose nie robi nic, aby zwolnić zarządzane obiekty w pamięci. Należy użyć metody Dispose, aby zwolnić zasoby "niezarządzane", w tym połączenia z bazami danych, mapy bitowe lub dowolne niezarządzane struktury, które można trzymać.

Jeśli mówisz o interfejsach, tak jak w komponentach wizualnych (Formularze, dialogi itp.), Staje się to nieco bardziej zagmatwane. W WinForms uważam, że gdy interfejs (wizualny) nie będzie już widoczny, zostanie oczyszczony i zebrane śmieci. Formularz zostanie odtworzony ponownie, gdy będzie potrzebny. W WPF, Windows i Strony nie są natychmiast niszczone. Są przechowywane w pamięci podręcznej przez cały okres istnienia aplikacji, chyba że zostaną specjalnie wyczyszczone przez programistę aplikacji. Poprawia to wydajność za pomocą aplikacji WPF, ale stanowi dodatkowy ciężar martwienia się o zasoby w aplikacji.

Zbieranie śmieci to całkowicie odrębny temat. Rzeczywiste uwolnienie zarządzanych obiektów z pamięci fizycznej występuje tutaj i jest całkowicie zależne od usługi usuwania śmieci i nie powinieneś normalnie martwić się, jak to działa.

Cheers

+0

-1 dla frazy "nie musisz rezygnować z ...". Prawdziwe dla zmiennych, niebezpiecznie fałszywe dla pól. –

+0

Dla reszty brakuje jakiejkolwiek perspektywy Delph. –

+0

Gdy klasa wykracza poza zakres, pola są czyszczone. Dlaczego musisz zerwać pola? Jeśli twoja klasa trzyma zasoby niezarządzane, musisz je wyczyścić w swojej implementacji metody Dispose. Usunięcie pola niekoniecznie spowoduje wyczyszczenie zasobów niezarządzanych. Pytanie dotyczyło również zarządzania pamięcią w języku C#. Brakowało mi wyraźnego linku między interfejsem Delphi a interfejsem C#, ale nie odczułem, że to pomniejsza mój wkład. –

8

Kluczową różnicą między Delphi i .NET w tej dziedzinie, w szczególności odnoszące się do interfejsów, jest zakaz deterministyczny charakter oczyszczania.

W Delphi całe użycie interfejsu jest zgodne z modelem COM. Oznacza to, że liczy się odniesienie. Jeśli klasa implementuje model zarządzania zliczany od zera, wówczas gdy liczba odwołań spadnie do zera, instancja obiektu zostanie zniszczona w tym punkcie.

UWAGA: Zarządzanie dożywotnią funkcją funkcji klasy. Aby zobaczyć to najbardziej wyraźnie, spojrzenie na realizację IUnknown.Release w TInterfacedObject:

function TInterfacedObject._Release: Integer; 
begin 
    Result := InterlockedDecrement(FRefCount); 
    if Result = 0 then 
    Destroy; 
end; 

Jeśli realizacja wydaniu nie zadzwonił Destroy, to obiekt będzie nie być Zniszczone, gdy licznik odniesień spadnie do zera i nadal będzie musiał być jawnie Dowolny poprzez odniesienie do obiektu. To może być używane w Delphi do tworzenia obiektów, które implementują interfejsy, ale które nie podlegają automatycznemu, referencyjnemu zliczaniu zarządzania cyklem życia (chociaż nie można uniknąć referencyjnego kodu zliczającego wstrzykniętego przez kompilator, tj. Wywołania AddRef i wydanie).

W .NET przede wszystkim nie ma liczenia odwołań jako takich. Garbage Collector działa w znacznie bardziej wyrafinowany sposób, którego szczegóły nie są bezpośrednio związane z tą dyskusją.

Podstawową różnicą jest to, że gdy obiekt nie jest już używany (ale jest to określane poza prostą liczbą odniesienia), NIE jest to punkt, w którym jest on niszczony w .NET.

Teoretycznie możliwe jest, że niewykorzystane obiekty będą kumulować się w aplikacji do znacznie późniejszego okresu eksploatacji procesu - szczególnie w aplikacjach wymagających dużej mocy obliczeniowej z kilkoma cyklami bezczynności. W .NET po prostu nie można być pewnym, że te nieużywane obiekty zostaną ostatecznie zwolnione.

Niektórzy twierdzą, że jest to Dobra Rzecz,, chociaż dezorientuje zwykłą praktykę czyszczenia zasobów, które są zablokowane lub są własnością obiektów, gdy te obiekty są niszczone, ponieważ zazwyczaj trzeba zwolnić te zablokowane/posiadane zasoby bardziej pilnie niż jest to możliwe dzięki czekaniu na Garbage Collectora. W tym miejscu pojawia się IDisposable. Szczegóły, które nie są bezpośrednio istotne, mogą być dalej badane w wolnym czasie.

+0

Dzięki za świetne wyjaśnienie - twoja odpowiedź i jeden z nich bardzo mi pomogły. – ronaldosantana

Powiązane problemy