Κατανοήστε και αποτρέψτε τις διαρροές μνήμης στους Δελφούς

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

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

Κάθε φορά που πρέπει να χρησιμοποιήσετε (δημιουργήσετε) ένα αντικείμενο στους Δελφούς, πρέπει να απελευθερώσετε τη μνήμη που καταναλώνεται (μία φορά δεν χρειάζεται πια). Σίγουρα, οι δοκιμαστές / τελικά μνήμες φύλαξης μπορεί να σας βοηθήσουν να αποτρέψετε διαρροές μνήμης. εξαρτάται από εσάς να προστατέψετε τον κωδικό σας.

Μια διαρροή μνήμης (ή πόρων) προκύπτει όταν το πρόγραμμα χάνει τη δυνατότητα να απελευθερώσει τη μνήμη που καταναλώνει. Επαναλαμβανόμενες διαρροές μνήμης αναγκάζουν τη χρήση μνήμης μιας διαδικασίας να αναπτύσσεται χωρίς όρια. Οι διαρροές μνήμης είναι ένα σοβαρό πρόβλημα - εάν έχετε έναν κώδικα που προκαλεί διαρροή μνήμης, σε μια τρέχουσα εφαρμογή 24/7, η εφαρμογή θα τρώει όλη τη διαθέσιμη μνήμη και τελικά θα κάνει το μηχάνημα να σταματήσει να ανταποκρίνεται.

instagram viewer

Διαρροές μνήμης στους Δελφούς

Το πρώτο βήμα για την αποφυγή διαρροών μνήμης είναι να καταλάβετε πώς συμβαίνουν. Αυτό που ακολουθεί είναι μια συζήτηση σχετικά με κάποιες κοινές παγίδες και βέλτιστες πρακτικές για τη συγγραφή μη-διαρροών κώδικα των Δελφών.

Στις περισσότερες (απλές) εφαρμογές των Δελφών, όπου χρησιμοποιείτε τα στοιχεία (Κουμπιά, Σημειώσεις, Επεξεργασίες κ.λπ.), αφήνετε μια φόρμα (κατά το σχεδιασμό), δεν χρειάζεται να φροντίζετε πάρα πολύ για τη διαχείριση μνήμης. Μόλις το στοιχείο τοποθετηθεί σε μια φόρμα, το έντυπο γίνεται ιδιοκτήτης και θα απελευθερώσει τη μνήμη που λαμβάνεται από τη συνιστώσα μόλις κλείσει η φόρμα (καταστραφεί). Το έντυπο, ως ιδιοκτήτης, είναι υπεύθυνο για την ανακατανομή μνήμης των συστατικών που φιλοξένησε. Με λίγα λόγια: τα στοιχεία μιας φόρμας δημιουργούνται και καταστρέφονται αυτόματα

Παραδείγματα διαρροών μνήμης

Σε οποιαδήποτε μη-ασήμαντη εφαρμογή Delphi, θα θελήσετε να παράδοση των στοιχείων Delphi κατά το χρόνο εκτέλεσης. Θα έχετε, επίσης, μερικές από τις δικές σας προσαρμοσμένες τάξεις. Ας υποθέσουμε ότι έχετε έναν TDeveloper κατηγορίας που έχει DoProgram μεθόδου. Τώρα, όταν πρέπει να χρησιμοποιήσετε την κλάση TDeveloper, δημιουργείτε μια παρουσία της κλάσης καλώντας το Δημιουργώ (κατασκευαστής). Η μέθοδος Δημιουργεί τη μνήμη για ένα νέο αντικείμενο και επιστρέφει μια αναφορά στο αντικείμενο.

var
zarko: TDeveloper
ξεκινήσει
zarko: = TMyObject. Δημιουργώ;
zarko. DoProgram;
τέλος;

Και εδώ είναι μια απλή διαρροή μνήμης!

Κάθε φορά που δημιουργείτε ένα αντικείμενο, πρέπει να απορρίψετε τη μνήμη που καταλαμβάνει. Για να απελευθερώσετε τη μνήμη από ένα αντικείμενο, πρέπει να καλέσετε το Ελεύθερος μέθοδος. Για να είμαστε απόλυτα σίγουροι, θα πρέπει επίσης να χρησιμοποιήσετε το μπλοκ try / finally:

var
zarko: TDeveloper
ξεκινήσει
zarko: = TMyObject. Δημιουργώ;
δοκιμάστε
zarko. DoProgram;
τελικά
zarko. Ελεύθερος;
τέλος;
τέλος;

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

Ορισμένες λέξεις προειδοποίησης: Εάν θέλετε να δημιουργήσετε μια δυναμική παράσταση ενός στοιχείου Delphi και να τον απελευθερώσετε κάποια στιγμή αργότερα, πάντα να περάσετε ως ιδιοκτήτης. Εάν δεν το κάνετε, μπορεί να δημιουργηθεί περιττός κίνδυνος, καθώς και προβλήματα επιδόσεων και συντήρησης κώδικα.

Εκτός από τη δημιουργία και την καταστροφή αντικειμένων χρησιμοποιώντας τις μεθόδους Δημιουργία και Δωρεάν, πρέπει επίσης να είστε πολύ προσεκτικοί όταν χρησιμοποιείτε πόρους "εξωτερικού" (αρχεία, βάσεις δεδομένων κ.λπ.).
Ας υποθέσουμε ότι πρέπει να λειτουργήσετε σε κάποιο αρχείο κειμένου. Σε ένα πολύ απλό σενάριο, όπου η μέθοδος AssignFile χρησιμοποιείται για τη συσχέτιση ενός αρχείου σε ένα δίσκο με ένα αρχείο μεταβλητή όταν τελειώσετε με το αρχείο, πρέπει να καλέσετε το CloseFile για να ξεκινήσετε το χειρισμό του αρχείου μεταχειρισμένος. Σε αυτό το σημείο δεν έχετε ρητή κλήση στο "Ελεύθερο".

var
F: TextFile;
S: συμβολοσειρά.
ξεκινήσει
AssignFile (F, 'c: \ somefile.txt');
δοκιμάστε
Readln (F, S).
τελικά
CloseFile (F);
τέλος;
τέλος;

Ένα άλλο παράδειγμα περιλαμβάνει τη φόρτωση εξωτερικών αρχείων DLL από τον κωδικό σας. Όποτε χρησιμοποιείτε το LoadLibrary, πρέπει να καλέσετε το FreeLibrary:

var
dllHandle: Thandle;
ξεκινήσει
dllHandle: = Loadlibrary ("MyLibrary. DLL ').
// κάνει κάτι με αυτό το DLL
αν dllHandle <> 0 τότε FreeLibrary (dllHandle);
τέλος;

Διαρροές μνήμης στο .NET;

Αν και με τους Delphi για το .NET ο συλλέκτης σκουπιδιών (GC) διαχειρίζεται τις περισσότερες εργασίες μνήμης, είναι πιθανό να υπάρχουν διαρροές μνήμης σε εφαρμογές .NET. Ακολουθεί μια συζήτηση για το άρθρο GC στους Δελφούς για .NET.

Πώς να αντιμετωπίσετε διαρροές μνήμης

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