Anatomie „Memory Leak“

hlasů
159

V .NET perspektivě:

  • Co je Memory Leak ?
  • Jak můžete zjistit, zda vaše těsnost aplikace? Jaké jsou důsledky?
  • Jak můžete zabránit nevracení paměti?
  • Pokud vaše aplikace má nevracení paměti, to jde pryč, když se proces ukončí nebo je zabit? Nebo úniky paměti v aplikaci vliv na ostatní procesy v systému i po ukončení procesu?
  • A co nespravovaný kód přístupné přes COM InterOp a / nebo P / Invoke?
Položena 01/08/2008 v 16:12
zdroj uživatelem
V jiných jazycích...                            


15 odpovědí

hlasů
106

Nejlepší vysvětlení jsem viděl, je v kapitole 7 volných Základy programování e-knihy .

Zjednodušeně řečeno, v .NET dochází k nevracení paměti při odkazované objekty kořeny, a proto nemůže být uvolněna. K tomu dochází náhodně, když se držet na referencí mimo zamýšlený rozsah.

Budete vědět, že máte úniky, když začnete dostat OutOfMemoryExceptions nebo vaše využití paměti stoupá rámec toho, co byste očekávali ( PerfMon má pěkné čítače paměti).

Pochopení .NET model paměti je, je nejlepší způsob, jak se vyhnout to. Konkrétně pochopení toho, jak garbage collector funguje a jak reference práce - opět odkazuji na kapitolu 7 e-knihy. Také mějte na paměti společných úskalí, pravděpodobně nejvíce obyčejné jsoucí události. Pokud objekt je registrována k události na objekt B , pak objekt A bude držet kolem, dokud objekt B zmizí, protože B uchovává odkaz . Řešením je zrušení registrace na akce, když budete hotovi.

Samozřejmě, dobrý profil paměť vám umožní vidět vaše objektů grafy a prozkoumat hnízdění / odkazování svých objektů, které mají zjistit, kde reference přicházejí a co kořenový objekt je zodpovědný ( red-gate mravenci profil , JetBrains dotMemory, memprofiler jsou opravdu dobré volby, nebo můžete použít pouze text WinDbg a SOS , ale já bych důrazně doporučujeme obchodní / vizuální produkt, pokud jste opravdový guru).

Věřím, že neřízený kód je předmětem jeho typické úniky paměti, že kromě sdílené odkazy jsou řízeny garbage collector. Možná se mýlím o tomto posledním bodě.

Odpovězeno 01/08/2008 v 16:28
zdroj uživatelem

hlasů
32

Přísně vzato, nevracení paměti spotřebovává paměť, která je „již nepoužívaný“ programem.

„Už ne použitý“ má více než jeden význam, mohlo by to znamenat „žádné další zmínky o ní“, který je zcela nepoužitelný, nebo by to mohlo znamenat, odkazoval, vymahatelné, nepoužitý ale program přesto udržuje odkazy. Teprve později se vztahuje na .NET dokonale řízených objektů . Nicméně, ne všechny třídy jsou dokonalé a na nějakém místě fundamentální neřízený implementace může dojít k úniku zdrojů trvale na tomto procesu.

Ve všech případech použití spotřebuje více paměti než je nezbytně třeba. Účinky boky, v závislosti na ammount unikly, může jít z nuly, zpomalení v důsledku nadměrného odběru na řadu paměťových výjimek a nakonec fatální chyby následuje ukončení nucené procesu.

Víte, že aplikace má problémy s pamětí při sledování ukazuje, že stále více a více paměti přiděleno do svého procesu po každém sběru odpadků cyklu . V takovém případě se buď udržet moc v paměti, nebo nějaké podkladové neřízený implementace netěsní.

U většiny těsnost zdroje jsou získány, když je proces ukončen, ale některé zdroje nejsou vždy vráceny v některých přesných případech GDI kurzorové kliky jsou notoricky známé za to. Samozřejmě, pokud máte Komunikace mezi mechanismem, paměti přidělené v druhém procesu by neměla být uvolněna, dokud to, že proces uvolní a ukončí.

Odpovězeno 01/08/2008 v 18:52
zdroj uživatelem

hlasů
28

Myslím, že „to, co je nevracení paměti“ a „Jaké jsou účinky“ otázky byly zodpovězeny již dobře, ale chtěl jsem přidat několik dalších věcí, na další otázky ...

Jak zjistit, zda vaše aplikace úniků

Jeden zajímavý způsob, jak je otevřít perfmon a přidejte stopy po # bytech ve všech haldách a # Gen 2 sbírkách , v každém případě při pohledu právě u vašeho procesu. Pokud vykonává určitou vlastnost způsobuje, že celková bajtů zvýšit, a že paměť zůstává přidělen po dalším sběru Gen 2, dalo by se říct, že funkce nevrací paměť.

Jak se bránit

Další dobré názory dostali. Jen bych dodal, že možná nejčastěji přehlíženy příčinou úniků paměti .NET je přidání obslužné rutiny událostí na objekty, aniž by jejich odstranění. Zpracování události připojené k objektu je formou odkazu na tento objekt, takže se zabrání shromažďování i po všechny další odkazy šly. Vždy se odpojit obsluhy událostí (pomocí -=syntaxe v jazyce C #).

Má únik jít pryč, když proces východy a co o COM interop?

Když se váš proces ukončí, všechny paměti mapovány do adresního prostoru je uvolněno do operačního systému, včetně veškeré objekty COM podává od dll. Poměrně zřídka, COM objekty mohou být podávány z oddělených procesů. V tomto případě, pokud váš proces ukončí, může stále být zodpovědné za paměť přidělené v jakémkoliv jiném procesu COM serveru, které jste použili.

Odpovězeno 15/08/2008 v 17:11
zdroj uživatelem

hlasů
18

Pokud potřebujete diagnostikovat nevracení paměti v .NET, zkontrolujte tyto odkazy:

http://msdn.microsoft.com/en-us/magazine/cc163833.aspx

http://msdn.microsoft.com/en-us/magazine/cc164138.aspx

Tyto články popisují, jak vytvořit výpis paměti vašeho procesu a jak ji analyzovat, takže můžete nejprve zjistit, zda váš únik je neřízený nebo řízeny, a pokud je řízeno, jak přijít na to, kde to pochází.

Microsoft má také novější nástroje na pomoc při generování crash skládek, nahradit ADPlus, nazvaný DebugDiag.

http://www.microsoft.com/downloads/details.aspx?FamilyID=28bd5941-c458-46f1-b24d-f60151d875a3&displaylang=en

Odpovězeno 15/08/2008 v 00:16
zdroj uživatelem

hlasů
18

Já bych definovat úniky paměti jako objekt není uvolnění všechny paměti přidělené po jeho dokončení. Zjistil jsem, že k tomu může dojít v aplikaci, pokud používáte Windows API a COM (tj neřízený kód, který má chybu v tom, nebo není správně řízena), v rámci av komponent třetích stran. Také jsem zjistil, není Uklízení po použití určitých objektů, jako pera může způsobit problém.

Osobně jsem trpěla nedostatek paměti výjimky, které mohou být způsobeny, ale nejsou exkluzivní k úniky paměti v Dot Net aplikací. (OOM mohou také přijít z připnout viz připnout Artical ). Pokud si nejste dostat chyby OOM, nebo je potřeba potvrdit, zda se jedná o únik paměti způsobí, že pak by jediný možný způsob, jak je profil vaší žádosti.

Také bych se pokusila zajistit následující:

a) Vše, co provádí IDisposable je umístěna buď pomocí finally nebo pomocí příkazu mezi ně patří štětce, pera a jiné (někteří lidé argumentují, nastavit vše na nic navíc)

b) Cokoliv, co má blízký způsob je opět uzavřen pomocí konečně nebo pomocí příkazu (i když jsem našel použití není vždy blízko podle toho, zda vyhlášen předmětu vně pomocí příkazu)

c) Pokud používáte nespravovaný kód / windows API je, že tyto jsou řešeny správně po. (Některé mají uklidit metody k uvolnění zdrojů)

Snad to pomůže.

Odpovězeno 01/08/2008 v 18:57
zdroj uživatelem

hlasů
15

Pomocí CLR Profiler od Microsoftu http://www.microsoft.com/downloads/details.aspx?familyid=86ce6052-d7f4-4aeb-9b7a-94635beebdda&displaylang=en je skvělý způsob, jak určit, které objekty jsou drží paměti, co se vykonávání toku vede k vytvoření těchto objektů, a také sledování, které objekty Live, kde na haldě (fragmentace, LOH, atd.).

Odpovězeno 16/08/2008 v 20:54
zdroj uživatelem

hlasů
14

Nejlepší vysvětlení toho, jak funguje garbage collector je Jeff Richters CLR pomocí C # knize (kap. 20). Čtení to dává velkou průpravu pro pochopení toho, jak objekty přetrvávají.

Jedním z nejčastějších příčin zakořenění objektů omylem je podle hákování událostí outisde třídy. Máte-li připojit externí událost

např

SomeExternalClass.Changed += new EventHandler(HandleIt);

a zapomněl odpojit na to, když budete likvidovat, pak SomeExternalClass má ref do vaší třídy.

Jak již bylo zmíněno výše, paměť profiler SciTech je vynikající při zobrazující kořeny objektů máte podezření, že se úniku.

Ale je tu také velmi rychlý způsob, jak zjistit konkrétní typ se stačí použít WnDBG (můžete použít i toto okno immediate VS.Net zatímco v příloze):

.loadby sos mscorwks
!dumpheap -stat -type <TypeName>

Teď dělat něco, co si myslíte, že bude disponovat objekty tohoto typu (např zavření okna). Je to šikovný zde mít tlačítko ladění někde, že bude spuštěn System.GC.Collect()několikrát.

Pak spusťte !dumpheap -stat -type <TypeName>znovu. Je-li počet nešel dolů, nebo nešel dolů tolik, jak byste očekávali, pak máte základ pro další vyšetřování. (Dostal jsem tento tip od semináři dané Ingo Rammer ).

Odpovězeno 27/08/2008 v 15:12
zdroj uživatelem

hlasů
14

Myslím, že v řízeném prostředí, únik by vám udržet zbytečné odkaz na velký kus paměti kolem.

Odpovězeno 01/08/2008 v 16:19
zdroj uživatelem

hlasů
10

Proč si lidé myslí, že k úniku paměti v .NET není stejné jako jakékoli jiné netěsnosti?

Únik paměti je, když se připojit ke zdroji a ne nechat to jít. To lze provést jak v spravovány a nespravovaném kódování.

Pokud jde o .NET a další programovací nástroje, tam byly myšlenky na odpadky sbírání a další způsoby, jak minimalizovat situace, které učiní váš únik aplikace. Ale nejlepší způsob, jak zabránit úniků paměti, je, že musíte pochopit svůj základní model paměti, a jak to funguje na platformě, kterou používáte.

Věřit, že GC a jiné magie bude uklidit nepořádek je krátká cesta k nevracení paměti a bude obtížné najít později.

Při kódování neřízený, obvykle ujistit, uklidit, víte, že zdroje, které berou do rukou, bude vaším úkolem vyčistit, ne školník je.

NET na druhé straně, mnoho lidí si myslí, že GC bude uklidit všechno. No, to dělá něco pro vás, ale je potřeba, aby se ujistil, že je to tak. NET má zabalit spoustu věcí, takže se nemusíte vždy vědět, pokud máte co do činění s spravovaného nebo nespravovaného zdroj, a je třeba, aby se ujistil, co to, co máte co do činění s. Manipulace s fonty, prostředky GDI, active directory, databází atd je obvykle věcí, které potřebujete dávat pozor.

V řízených podmínek dám krk na lince říci, že nemá jít pryč, jakmile proces je zabit / odstraněna.

Vidím, že spousta lidí, kteří mají to i když, a já opravdu doufám, že to skončí. Nemůžete požádat uživatele ukončit aplikaci vyčistit nepořádek! Podívejte se na prohlížeč, který může být IE, FF atd, pak open, řekněme, Google Reader, ať to zůstane několik dní, a podívat se na to, co se děje.

Pokud potom otevřít jinou záložku v prohlížeči, surfovat na nějakém místě, zavřete kartu, který hostil druhou stránku, která učinila únik prohlížeče, myslíš, že prohlížeč bude uvolnění paměti? Ne tak s IE. Na mém počítači IE snadno jíst 1 GiB paměti v krátkém čase (cca 3-4 dny), pokud mohu použít službu Google Reader. Některé newspages jsou ještě horší.

Odpovězeno 01/09/2008 v 13:19
zdroj uživatelem

hlasů
10

Myslím, že v řízeném prostředí, únik by vám udržet zbytečné odkaz na velký kus paměti kolem.

Absolutně. Také, a to pomocí metody .Dispose () na jedno použití předmětů v případě potřeby může způsobit mem netěsnosti. Nejjednodušší způsob, jak to udělat, je s využitím bloku, protože to automaticky spustí .Dispose () na konci:

StreamReader sr;
using(sr = new StreamReader("somefile.txt"))
{
    //do some stuff
}

A pokud si vytvořit třídu, která je pomocí neřízené objekty, pokud není správně uplatňovat IDisposable, ty by mohly být příčinou úniků paměti pro uživatele vaší třídy je.

Odpovězeno 05/08/2008 v 23:47
zdroj uživatelem

hlasů
9

Všechny úniky paměti jsou vyřešeny ukončení programu.

Úniku dostatek paměti a operační systém může rozhodnout, že k vyřešení problému, vaším jménem.

Odpovězeno 04/08/2008 v 15:09
zdroj uživatelem

hlasů
9

Budu souhlasit s Bernardem, aby NET, co by k úniku mem.

Dalo by se profil vaší žádosti vidět jeho využití paměti, a určit, že pokud jeho správu velké množství paměti, když to by nemělo být by se dalo říct, že má únik.

V řízených podmínek dám krk na lince říci, že nemá jít pryč, jakmile proces je zabit / odstraněna.

Neřízený kód je jeho vlastní zvíře a existuje-li únik v něm bude následovat standardní pam. úniku definici.

Odpovězeno 01/08/2008 v 16:23
zdroj uživatelem

hlasů
7

Také mějte na paměti, že .NET má dvě hromady, jedním z nich je velký objekt haldy. Věřím, že objekty zhruba 85k nebo větší jsou uvedeny na této haldě. Tato hromada má různá pravidla životnost než běžný haldy.

Pokud vytváříte velké paměťové struktury (slovník nebo seznam je), že by moudré jít vyhledávání, jaké přesné pravidla.

Pokud jde o znovuzískání paměti při ukončení procesu, pokud vaše běží Win98 nebo ekvivalenty, všechno je uvolněna zpět do operačního systému na ukončení. Výjimkou jsou pouze věci, které jsou otevřeny křížové proces a jiný proces má stále otevřený zdroj.

COM objekty mohou být ošidné tho. Pokud jste vždy používat IDisposevzor, budete v bezpečí. Ale já jsem narazit na několik sestavení interop, které implementují IDispose. Klíčem je zde zavolat Marshal.ReleaseCOMObject, když jste s ním udělal. COM objekty nadále používat standardní referenční COM počítání.

Odpovězeno 07/08/2008 v 14:17
zdroj uživatelem

hlasů
6

Zjistil jsem, .Net Memory Profiler velmi dobrou pomoc při hledání úniků paměti v .Net. Není to zdarma, jako Microsoft CLR Profiler, ale je rychlejší a do té míry, podle mého názoru. A

Odpovězeno 20/08/2008 v 19:39
zdroj uživatelem

hlasů
1

Jedna z definic je: Nelze uvolnit nedostupný paměť, která již nemůže být přiděleny novému postupu při provádění rozdělení procesu. To může zejména být léčeny za použití chromatografických technik nebo detekována automatizovaných nástrojů.

Pro více informací navštivte http://all-about-java-and-weblogic-server.blogspot.in/2014/01/what-is-memory-leak-in-java.html .

Odpovězeno 27/08/2014 v 16:22
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more