
Σε .NET προοπτική:


* Τι είναι **[Διαρροή μνήμης](http://en.wikipedia.org/wiki/Memory_leak)** ;
* Πώς μπορείτε να προσδιορίσετε αν διαρροές αίτησή σας; Ποιες είναι οι συνέπειες;
* Πώς μπορείτε να αποφευχθεί η διαρροή μνήμης;
* Εάν η εφαρμογή σας έχει απώλεια μνήμης, δεν θα πάει μακριά, όταν η διαδικασία εξέρχεται ή σκοτώνεται; Ή μήπως διαρροές μνήμης στην εφαρμογή σας επηρεάζουν άλλες διεργασίες στο σύστημα, ακόμη και μετά την ολοκλήρωση της διαδικασίας;
* Και τι γίνεται με μη διαχειριζόμενο κώδικα πρόσβαση μέσω COM διαλειτουργικότητα ή / και P / Κλήση;

 
Ανατομία ενός «Memory Leak»
===========================



Η καλύτερη εξήγηση που έχω δει είναι στο κεφάλαιο 7 των ελεύθερων [Ιδρύματα Προγραμματισμού e-book](http://codebetter.com/karlseguin/2008/06/25/foundations-of-programming-ebook/) .


Βασικά, σε **ΝΕΤ** παρουσιάζεται διαρροή μνήμης όταν τα αντικείμενα αναφοράς τις ρίζες και έτσι δεν μπορεί να σκουπίδια συλλέγονται. Αυτό συμβαίνει κατά λάθος, όταν κρατάτε για τις αναφορές πέρα από το σκοπούμενο πεδίο εφαρμογής.


Θα γνωρίζετε ότι έχετε διαρροές όταν ξεκινάτε να πάρει OutOfMemoryExceptions ή τη χρήση της μνήμης σας ανεβαίνει πέρα από αυτό που θα περίμενε κανείς ( **PerfMon** έχει ωραία μετρητές μνήμης).


Κατανόηση **ΝΕΤ** μοντέλο μνήμης «s είναι ο καλύτερος τρόπος για σας να αποφευχθεί αυτό. Συγκεκριμένα, την κατανόηση του πώς λειτουργεί ο συλλέκτης σκουπιδιών και πώς αναφορές λειτουργούν - και πάλι, σας παραπέμπω στο κεφάλαιο 7 του e-book. Επίσης, να λαμβάνει υπόψη της τις κοινές παγίδες, ίσως τα πιο κοινά είναι τα γεγονότα. Εάν το αντικείμενο **Α** έχει καταχωρηθεί σε μια εκδήλωση στο αντικείμενο **Β** , τότε αντιρρήσεις **Α** θα μείνω μέχρι το αντικείμενο **Β** εξαφανιστεί λόγω **B** κατέχει αναφορά στο **Α** . Η λύση είναι να καταργήσετε τις εκδηλώσεις σας, όταν τελειώσετε.


Φυσικά, ένα καλό προφίλ μνήμης θα σας αφήσει να δείτε το αντικείμενο γραφήματα σας και να εξερευνήσετε το φώλιασμα / αναφορά των αντικειμένων σας για να δείτε πού είναι οι αναφορές προέρχονται από και ποια ρίζα αντικείμενο είναι υπεύθυνος ( [προφίλ μυρμήγκια κόκκινο-πύλη](http://www.red-gate.com/products/ants_memory_profiler/index.htm) , JetBrains dotMemory, [memprofiler](http://memprofiler.com/) είναι πραγματικά καλό επιλογές, ή μπορείτε να χρησιμοποιήσετε το κείμενο-μόνο **WinDbg** και **SOS** , αλλά θα ήθελα να συνιστούμε ένα εμπορικό / οπτική του προϊόντος, εκτός αν είστε ένας πραγματικός γκουρού).


Πιστεύω μη διαχειριζόμενο κώδικα υπόκειται σε τυπικό διαρροές μνήμης, εκτός από το ότι μοιράζονται τις αναφορές που διαχειρίζεται τον συλλέκτη σκουπιδιών. Μπορεί να κάνω λάθος σχετικά με αυτό το τελευταίο σημείο.

 

Για να κυριολεκτήσουμε, μια διαρροή μνήμης καταναλώνει μνήμη που είναι «δεν χρησιμοποιείται πλέον» από το πρόγραμμα.


«Χρησιμοποιείται Δεν είναι πλέον» έχει περισσότερες από μία έννοια, θα μπορούσε να σημαίνει «περισσότερο αναφορά σε αυτό», δηλαδή, εντελώς ανεπανόρθωτο, ή θα μπορούσε να σημαίνει, αναφέρεται, αποδίδονται, αχρησιμοποίητο αλλά το πρόγραμμα διατηρεί τις αναφορές ούτως ή άλλως. Μόνο η τελευταία ισχύει για .NET για **τέλεια διαχείριση αντικειμένων** . Ωστόσο, δεν είναι όλες οι τάξεις είναι τέλεια και σε κάποιο σημείο μια υποκείμενη χωρίς έλεγχο εφαρμογής θα μπορούσε να διαρρεύσει μόνιμα πόρους για αυτή τη διαδικασία.


Σε όλες τις περιπτώσεις, η εφαρμογή καταναλώνει περισσότερη μνήμη από τις αυστηρά αναγκαίες. Τα αποτελέσματα πλευρές, ανάλογα με την ammount διαρρεύσει, θα μπορούσε να πάει από κανένα, σε επιβράδυνση προκαλείται από την υπερβολική συγκέντρωση, με μια σειρά από εξαιρέσεις μνήμης και, τέλος, ένα μοιραίο λάθος που ακολουθείται από τη λήξη αναγκαστική διαδικασία.


Ξέρετε μια εφαρμογή έχει ένα πρόβλημα μνήμης, όταν η παρακολούθηση δείχνει ότι όλο και εκχωρείται περισσότερη μνήμη για τη διαδικασία σας **μετά από κάθε κύκλο συλλογής σκουπιδιών** . Σε αυτή την περίπτωση, μπορείτε είτε διατηρώντας πάρα πολύ στη μνήμη, ή κάποια υποκείμενα χωρίς έλεγχο εφαρμογής έχει διαρροή.


Για τις περισσότερες διαρροές, οι πόροι ανακτώνται όταν τερματίζεται η διαδικασία, ωστόσο ορισμένοι πόροι δεν είναι πάντοτε ανακτώνται σε ορισμένες συγκεκριμένες περιπτώσεις, GDI λαβές δρομέα είναι διαβόητη για αυτό. Φυσικά, αν έχετε ένα μηχανισμό επικοινωνίας μεταξύ διεργασιών, τη μνήμη που διατίθεται σε άλλες διαδικασία δεν θα πρέπει να απελευθερωθεί μέχρι το ότι η διαδικασία αυτή απελευθερώνει ή τερματίζεται.

 

Νομίζω ότι το «τι είναι μια διαρροή μνήμης» και «ποιες είναι οι συνέπειες» έχουν ερωτήσεις έχουν απαντηθεί ήδη καλά, αλλά ήθελα να προσθέσω μερικά ακόμη πράγματα για τις άλλες ερωτήσεις ...


**Πώς να καταλάβετε εάν οι διαρροές της αίτησής σας**


Ένας ενδιαφέρων τρόπος είναι να ανοίξετε *perfmon* και προσθέστε τα ίχνη για *# bytes σε όλες τις σωρούς* και *# συλλογές Gen 2* , σε κάθε περίπτωση, κοιτάζοντας μόνο σε διαδικασία σας. Εάν ασκούν ένα ιδιαίτερο χαρακτηριστικό προκαλεί το σύνολο των bytes για την αύξηση, και ότι η μνήμη παραμένει διατεθεί μετά την επόμενη συλλογή Gen 2, θα μπορούσαμε να πούμε ότι η λειτουργία διαρροές μνήμης.


**Πώς να αποτρέψει**


Άλλες καλές απόψεις έχουν δοθεί. Θα ήθελα να προσθέσω μόνο ότι ίσως η *πιο συχνά παραβλέπεται* αιτία των διαρροών μνήμης NET είναι να προσθέσετε χειρισμού συμβάντων σε αντικείμενα χωρίς να αφαιρεθούν. Ένα πρόγραμμα χειρισμού συμβάντων που συνδέονται με ένα αντικείμενο είναι μια μορφή αναφοράς σε αυτό το αντικείμενο, έτσι θα εμποδίσει την είσπραξη ακόμη και μετά όλες οι άλλες αναφορές έχουν περάσει. Να θυμάστε πάντα να αποσπάσει χειρισμού συμβάντων (χρησιμοποιώντας τη `-=`σύνταξη σε C #).


**Μήπως η διαρροή πάει μακριά όταν τις εξόδους της διαδικασίας, και τι γίνεται με COM διαλειτουργικότητας;**


Όταν εξόδους διαδικασία σας, όλοι μνήμη χαρτογραφήθηκαν στο χώρο διευθύνσεων του είναι παρμένο από το λειτουργικό σύστημα, συμπεριλαμβανομένων τυχόν αντικείμενα COM εξυπηρετούνται από τα αρχεία DLL. Συγκριτικά σπάνια, COM αντικείμενα μπορούν να εξυπηρετούνται από ξεχωριστές διαδικασίες. Σε αυτήν την περίπτωση, κατά την διαδικασία σας έξοδο, μπορείτε ακόμα να είναι υπεύθυνη για τη μνήμη που διατίθεται σε όλες τις διαδικασίες του διακομιστή COM που χρησιμοποιείται.

 

Αν χρειαστεί να διαγνώσει μια διαρροή μνήμης στη ΝΕΤ, ελέγξτε αυτούς τους συνδέσμους:


[http://msdn.microsoft.com/en-us/magazine/cc163833.aspx](https://web.archive.org/web/20141203155344/http://msdn.microsoft.com/en-us/magazine/cc163833.aspx)


[http://msdn.microsoft.com/en-us/magazine/cc164138.aspx](https://web.archive.org/web/20150102222036/http://msdn.microsoft.com/en-us/magazine/cc164138.aspx)


Τα άρθρα αυτά περιγράφουν πώς να δημιουργήσετε ένα ένδειξης σφαλμάτων μνήμης της διαδικασίας σας και πώς να το αναλύσουμε, ώστε να μπορείτε να καθορίσετε πρώτα εάν διαρροή σας είναι χωρίς έλεγχο ή διαχείριση, και αν καταφέρει, πώς να καταλάβω πού προέρχεται.


Η Microsoft έχει επίσης ένα νεότερο εργαλείο για να βοηθήσει με τη δημιουργία χωματερές συντριβή, να αντικαταστήσει Adplus, που ονομάζεται DebugDiag.


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

 

Θα καθορίσει τις διαρροές μνήμης ως αντικείμενο δεν απελευθερώνοντας όλη τη μνήμη που διατίθεται μετά την ολοκλήρωση. Έχω διαπιστώσει ότι αυτό μπορεί να συμβεί στην αίτησή σας, αν χρησιμοποιείτε το Windows API και COM (δηλαδή μη διαχειριζόμενο κώδικα που έχει ένα bug σε αυτό ή δεν διαχειρίζεται σωστά), στο πλαίσιο και εξαρτημάτων τρίτων. Έχω, επίσης, δεν βρέθηκε εξουσιοδότηση μετά τη χρήση ορισμένων αντικειμένων όπως στυλό μπορεί να προκαλέσει το θέμα.


Προσωπικά έχω υποστεί Από Εξαιρέσεις μνήμη η οποία μπορεί να προκληθεί, αλλά δεν είναι αποκλειστικά για διαρροές μνήμης σε dot Net Applications. (Oom μπορεί επίσης να προέρχεται από καρφώνει δείτε [Καρφίτσωμα Artical](https://blogs.msdn.com/yunjin/archive/2004/01/27/63642.aspx) ). Αν δεν πάρει τα λάθη Oom ή πρέπει να επιβεβαιώσει αν πρόκειται για μια διαρροή μνήμης που προκαλεί τότε ο μόνος τρόπος είναι να το προφίλ της αίτησής σας.


Θα προσπαθήσουμε επίσης και να εξασφαλίσει τα εξής:


α) Ό, τι εφαρμόζει Idisposable είναι διατεταγμένο είτε χρησιμοποιώντας ένα τέλος μπλοκάρουν ή η χρήση δήλωσης αυτά περιλαμβάνουν πινέλα, στυλό κλπ (κάποιοι υποστηρίζουν για να ρυθμίσετε τα πάντα για τίποτα εκτός) 


β) Οτιδήποτε που έχει στενό μέθοδο κλείνει και πάλι χρησιμοποιώντας τέλος ή την χρήση δήλωση (αν και έχω βρεθεί χρησιμοποιείτε δεν είναι πάντα κοντά ανάλογα με το αν έχετε δηλώσει το αντικείμενο έξω από το χρησιμοποιούν δήλωση)


γ) Εάν χρησιμοποιείτε μη διαχειριζόμενο κώδικα / windows API είναι ότι αυτά αντιμετωπίζονται σωστά μετά. (Μερικά έχουν καθαρίσει μεθόδους για να απελευθερώσει πόρους)


Η ελπίδα αυτό βοηθά.

 

Χρησιμοποιώντας CLR Profiler από τη Microsoft <http://www.microsoft.com/downloads/details.aspx?familyid=86ce6052-d7f4-4aeb-9b7a-94635beebdda&displaylang=en> είναι ένας πολύ καλός τρόπος για να καθορίσει τη μνήμη οποία τα αντικείμενα που κρατάτε, τι εκτέλεση οδηγεί ροής για τη δημιουργία αυτών των αντικειμένων, καθώς και την παρακολούθηση ποια αντικείμενα ζωντανά σε ποιο σημείο του σωρού (κατακερματισμός, ΑΕ, κλπ).

 

Η καλύτερη εξήγηση για το πώς λειτουργεί ο συλλέκτης σκουπιδιών είναι ο Jeff Richters [CLR μέσω C #](https://www.microsoftpressstore.com/store/clr-via-c-sharp-9780735667457) βιβλίο, (Χ. 20). Διαβάζοντας αυτό δίνει μια μεγάλη γείωσης για την κατανόηση του πώς επιμένουν αντικείμενα.


Μία από τις πιο κοινές αιτίες της ριζοβολία αντικειμένων τυχαία είναι, συνδέοντας γεγονότα outisde μια τάξη. Εάν συνδέσετε μια εξωτερική εκδήλωση


π.χ



```
SomeExternalClass.Changed += new EventHandler(HandleIt);

```

και να ξεχάσουμε να απαγκιστρώσει σε αυτό όταν πρόκειται να διαθέσετε, τότε SomeExternalClass έχει διαιτητή στην τάξη σας.


Όπως προαναφέρθηκε, η [profiler μνήμη SciTech](http://memprofiler.com) είναι εξαιρετική σε σας δείχνει τις ρίζες των αντικειμένων που ύποπτος είναι διαρροή. 


Υπάρχει όμως και ένας πολύ γρήγορος τρόπος για να ελέγξετε έναν συγκεκριμένο τύπο είναι απλά χρησιμοποιήστε WnDBG (μπορείτε ακόμη να χρησιμοποιήσετε αυτό στο άμεσο παράθυρο VS.NET ενώ συνημμένο):



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

```

Τώρα κάνει κάτι που νομίζετε ότι θα διαθέσει τα αντικείμενα αυτού του τύπου (π.χ. κλείσετε ένα παράθυρο). Είναι χρήσιμο εδώ να έχουμε ένα κουμπί debug κάπου που θα τρέξει `System.GC.Collect()`μια-δυο φορές.


Στη συνέχεια, εκτελέστε `!dumpheap -stat -type <TypeName>`ξανά. Εάν ο αριθμός δεν πάει κάτω, ή δεν πάει κάτω όσο θα περιμένατε, τότε έχετε μια βάση για περαιτέρω έρευνα. (Πήρα αυτή την άκρη από ένα σεμινάριο που έδωσε [Ingo κριό](http://www.thinktecture.com/staff/ingo) ).

 

Υποθέτω ότι σε ένα διαχειριζόμενο περιβάλλον, η διαρροή θα σας κρατώντας μια περιττή αναφορά σε ένα μεγάλο κομμάτι της μνήμης γύρω.

 

Γιατί οι άνθρωποι πιστεύουν ότι μια διαρροή μνήμης στη ΝΕΤ, δεν είναι η ίδια με οποιαδήποτε άλλη διαρροή;


Μια διαρροή μνήμης είναι όταν συνδέετε σε έναν πόρο και να μην αφήσει να πάει. Μπορείτε να το κάνετε αυτό, τόσο στη διαχείριση και χωρίς έλεγχο κωδικοποίηση.


Όσον αφορά .NET, και άλλα εργαλεία προγραμματισμού, υπήρξαν ιδέες για τα σκουπίδια συλλογή, και άλλοι τρόποι ελαχιστοποίησης καταστάσεις που θα κάνουν διαρροή αίτησή σας. Όμως, η καλύτερη μέθοδος για την πρόληψη των διαρροών μνήμης είναι ότι θα πρέπει να κατανοήσουν ότι η προσομοίωση της μνήμης σας, και πώς λειτουργεί τα πράγματα, σχετικά με την πλατφόρμα που χρησιμοποιείτε.


Πιστεύοντας ότι GC και άλλα μαγικά θα καθαρίσει το χάλι σας είναι η σύντομη τρόπος για διαρροές μνήμης, και θα είναι δύσκολο να βρεθεί αργότερα.


Κατά την κωδικοποίηση χωρίς έλεγχο, που κανονικά φροντίστε να καθαρίσει, ξέρετε ότι οι πόροι που παίρνετε στα χέρια τους, θα είναι δική σας ευθύνη να καθαρίσει, όχι ο επιστάτης του.


Στη ΝΕΤ από την άλλη πλευρά, πολλοί άνθρωποι πιστεύουν ότι η GC θα καθαρίσει τα πάντα. Λοιπόν, το κάνει κάποια για σας, αλλά θα πρέπει να βεβαιωθείτε ότι είναι έτσι. .NET έχει τυλίξει πολλά πράγματα, οπότε δεν ξέρεις πάντα αν έχουμε να κάνουμε με ένα διαχειρίζεται ή χωρίς έλεγχο των πόρων, και θα πρέπει να βεβαιωθείτε ότι ό, τι ό, τι έχουμε να κάνουμε με. Χειρισμός γραμματοσειρές, GDI πόρους, Active Directory, βάσεις δεδομένων κλπ είναι συνήθως πράγματα που πρέπει να προσέξετε.



> 
> Σε κατάφερε όρους που θα θέσει το λαιμό μου στη γραμμή για να πω ότι δεν υποχωρεί μόλις ολοκληρωθεί η διαδικασία σκοτώνεται / αφαιρεθεί.
> 
> 
> 


Βλέπω πολλούς ανθρώπους να έχουν αυτό όμως, και πραγματικά ελπίζω αυτό θα τελειώσει. Δεν μπορείτε να ζητήσει από το χρήστη να τερματίσει την εφαρμογή σας για να καθαρίσει το χάλι σας! Ρίξτε μια ματιά σε ένα πρόγραμμα περιήγησης, που μπορεί να είναι IE, FF κλπ, στη συνέχεια, ανοίξτε, ας πούμε, το Google Reader, αφήστε το να μείνει για μερικές μέρες, και να δούμε τι θα συμβεί.


Εάν στη συνέχεια, ανοίξτε μια άλλη καρτέλα στο πρόγραμμα περιήγησης, σερφάρετε σε κάποια ιστοσελίδα, στη συνέχεια, κλείστε την καρτέλα που φιλοξένησε την άλλη σελίδα που έκανε τη διαρροή του προγράμματος περιήγησης, νομίζετε ότι ο browser θα κυκλοφορήσει τη μνήμη; Όχι τόσο με IE. Στον υπολογιστή μου IE θα φάνε εύκολα 1 GiB της μνήμης σε ένα σύντομο χρονικό διάστημα (περίπου 3-4 ημέρες) αν μπορώ να χρησιμοποιήσω το Google Reader. Μερικοί newspages είναι ακόμα χειρότερα.

 


> 
> Υποθέτω ότι σε ένα διαχειριζόμενο περιβάλλον, η διαρροή θα σας κρατώντας μια περιττή αναφορά σε ένα μεγάλο κομμάτι της μνήμης γύρω.
> 
> 
> 


Απολύτως. Επίσης, δεν χρησιμοποιώντας τη μέθοδο .Dispose () σχετικά με το διαθέσιμο αντικείμενα όταν ενδείκνυται μπορεί να προκαλέσει mem διαρροές. Ο ευκολότερος τρόπος να γίνει αυτό είναι με τη χρήση μπλοκ, διότι εκτελεί αυτόματα .Dispose () στο τέλος:



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

```

Και εάν δημιουργήσετε μια τάξη που χρησιμοποιεί διαχειριζόμενων αντικειμένων, αν δεν την εφαρμογή IDisposable σωστά, θα μπορούσε να προκαλέσει διαρροές μνήμης για τους χρήστες της τάξης σας.

 

Όλες οι διαρροές μνήμης επιλυθούν με τη λήξη του προγράμματος. 


Διαρροή αρκετή μνήμη και το λειτουργικό σύστημα μπορεί να αποφασίσει να επιλύσει το πρόβλημα για λογαριασμό σας.

 

Θα συμφωνήσω με τον Bernard ως προς το .net τι μια διαρροή μν θα είναι.


Θα μπορούσατε προφίλ αίτησή σας για να δείτε τη χρήση της μνήμης του, και να καθορίσει ότι αν της διαχείρισης πολλή μνήμη, όταν δεν θα πρέπει να μπορείς να πεις ότι έχει διαρροή.


Σε κατάφερε όρους που θα θέσει το λαιμό μου στη γραμμή για να πω ότι δεν υποχωρεί μόλις ολοκληρωθεί η διαδικασία σκοτώνεται / αφαιρεθεί.


Χωρίς έλεγχο κώδικας είναι δική θηρίο και αν μια διαρροή υπάρχει μέσα σε αυτό, θα ακολουθήσει ένα πρότυπο mem. διαρρεύσει ορισμός.

 

Επίσης, να έχετε κατά νου ότι .NET έχει δύο σωρούς, ένα είναι το μεγάλο αντικείμενο σωρού. Πιστεύω ότι τα αντικείμενα της περίπου 85k ή μεγαλύτερο βάλει σε αυτό το σωρό. Αυτή η σωρός διαθέτει διαφορετικούς κανόνες ζωής από το κανονικό σωρό.


Αν θέλετε να δημιουργήσετε μεγάλες δομές μνήμης (Λεξικό του ή της λίστας) θα ήταν φρόνιμο να πάει αναζήτηση ποιες είναι οι ακριβείς κανόνες.


Όσον αφορά την ανάκτηση της μνήμης για τον τερματισμό της διαδικασίας, εκτός αν τρέχει σας Win98 ή ισοδύναμα, τα πάντα απελευθερώνεται πίσω στο λειτουργικό σύστημα τερματισμού. Οι μόνες εξαιρέσεις είναι τα πράγματα που ανοίγονται cross-διαδικασία και μια άλλη διαδικασία εξακολουθεί να έχει τον πόρο ανοιχτή.


COM αντικείμενα μπορεί να είναι δύσκολο εν τούτοις. Εάν χρησιμοποιείτε πάντα το `IDispose`μοτίβο, θα είστε ασφαλείς. Αλλά έχω τρέξει σε μερικά σύνολα διαλειτουργικότητας που εφαρμόζουν `IDispose`. Το κλειδί εδώ είναι να καλέσετε `Marshal.ReleaseCOMObject`όταν τελειώσετε με αυτό. Οι COM αντικείμενα εξακολουθούν να χρησιμοποιούν το πρότυπο μέτρησης αναφοράς COM.

 

Βρήκα [Καθαρά μνήμης Profiler](http://memprofiler.com/) μια πολύ καλή βοήθεια κατά την εύρεση διαρροών μνήμης σε .Net. Δεν είναι δωρεάν, όπως το Microsoft CLR Profiler, αλλά είναι πιο γρήγορο και περισσότερο στο σημείο, κατά τη γνώμη μου. ΕΝΑ

 

Ένας ορισμός είναι: **Δεν είναι δυνατή η απελευθέρωση απρόσιτο μνήμης, τα οποία δεν μπορούν πλέον να διατεθούν σε νέα διαδικασία κατά την εκτέλεση της διαδικασίας κατανομής. Μπορεί ως επί το πλείστον να θεραπευτεί με τη χρήση τεχνικών GC ή να ανιχνευθούν από τα αυτοματοποιημένα εργαλεία.**


Για περισσότερες πληροφορίες, παρακαλώ επισκεφθείτε <http://all-about-java-and-weblogic-server.blogspot.in/2014/01/what-is-memory-leak-in-java.html> .

 