Διαχείριση μνήμης σε Java
Τι είναι η Stack Memory;
Η στοίβα στη java είναι ένα τμήμα της μνήμης που περιέχει μεθόδους, τοπικές μεταβλητές και μεταβλητές αναφοράς. Η μνήμη στοίβας αναφέρεται πάντα με τη σειρά Last-In-First-Out. Οι τοπικές μεταβλητές δημιουργούνται στη στοίβα.
Τι είναι η μνήμη Heap;
Το Heap είναι ένα τμήμα της μνήμης που περιέχει αντικείμενα και μπορεί επίσης να περιέχει μεταβλητές αναφοράς. Οι μεταβλητές παράδειγμα δημιουργούνται στο σωρό.
Εκχώρηση μνήμης σε Java
Εκχώρηση μνήμης σε Java είναι η διαδικασία κατά την οποία τα τμήματα εικονικής μνήμης παραμερίζονται σε ένα πρόγραμμα για την αποθήκευση των μεταβλητών και των παρουσιών δομών και κλάσεων. Ωστόσο, η μνήμη δεν εκχωρείται σε ένα αντικείμενο κατά τη δήλωση, αλλά δημιουργείται μόνο μια αναφορά. Για την εκχώρηση μνήμης του αντικειμένου, χρησιμοποιείται η μέθοδος new(), οπότε στο αντικείμενο εκχωρείται πάντα μνήμη στο σωρό.
Η Java Η κατανομή μνήμης χωρίζεται στις ακόλουθες ενότητες:
- Σωρός
- Στοίβα
- Κώδικας
- Στατικός
Αυτή η διαίρεση της μνήμης απαιτείται για την αποτελεσματική διαχείρισή της.
- Η κωδικός ενότητα περιέχει το δικό σας bytecode.
- Η Στοίβα τμήμα της μνήμης περιέχει μεθόδους, τοπικές μεταβλητές και μεταβλητές αναφοράς.
- Η Σωρός ενότητα περιέχει Αντικείμενα (μπορεί επίσης να περιέχει μεταβλητές αναφοράς).
- Η Στατικός ενότητα περιέχει Στατικά δεδομένα/μέθοδοι.
Διαφορά μεταξύ τοπικής και μεταβλητής παρουσίας
Μεταβλητή παρουσίας δηλώνεται μέσα σε μια κλάση αλλά όχι μέσα σε μια μέθοδο
class Student{ int num; // num is instance variable public void showData{}
Τοπική μεταβλητή δηλώνονται μέσα a μέθοδος που περιλαμβάνει μέθοδος επιχειρήματα.
public void sum(int a){ int x = int a + 3; // a , x are local variables; }
Διαφορά μεταξύ Stack και Heap
Πατήστε εδώ εάν το βίντεο δεν είναι προσβάσιμο
Ας πάρουμε ένα παράδειγμα για να το καταλάβουμε καλύτερα. Σκεφτείτε ότι η κύρια μέθοδος σας καλεί τη μέθοδο m1
public void m1{ int x=20 }
Στη στοίβα java, θα δημιουργηθεί ένα πλαίσιο από τη μέθοδο m1.
Η μεταβλητή X σε m1 θα δημιουργηθεί επίσης στο πλαίσιο για m1 στη στοίβα. (Δείτε την εικόνα παρακάτω).
Η μέθοδος m1 καλεί τη μέθοδο m2. Στη στοίβα java, δημιουργείται ένα νέο πλαίσιο για m2 πάνω από το πλαίσιο m1.
Οι μεταβλητές b και c θα δημιουργηθούν επίσης σε ένα πλαίσιο m2 σε μια στοίβα.
public void m2(int b){ boolean c; }
Η ίδια μέθοδος m2 καλεί τη μέθοδο m3. Και πάλι δημιουργείται ένα πλαίσιο m3 στην κορυφή της στοίβας (δείτε την εικόνα παρακάτω).
Τώρα ας υποθέσουμε ότι η μέθοδος m3 δημιουργεί ένα αντικείμενο για την κλάση "Account", η οποία έχει δύο μεταβλητή περιπτώσεων int p και int q.
Account { Int p; Int q; }
Εδώ είναι ο κώδικας για τη μέθοδο m3
public void m3(){ Account ref = new Account(); // more code }
Η δήλωση new Account() θα δημιουργήσει ένα αντικείμενο λογαριασμού σε σωρό.
Η μεταβλητή αναφοράς "ref" θα δημιουργηθεί σε μια στοίβα java.
Ο τελεστής εκχώρησης "=" θα κάνει μια μεταβλητή αναφοράς για να δείχνει το αντικείμενο στο Heap.
Μόλις η μέθοδος ολοκληρώσει την εκτέλεσή της. Η ροή του ελέγχου θα επιστρέψει στη μέθοδο κλήσης. Η οποία σε αυτή την περίπτωση είναι η μέθοδος m2.
Η στοίβα από τη μέθοδο m3 θα ξεπλυθεί.
Εφόσον η μεταβλητή αναφοράς δεν θα δείχνει πλέον το αντικείμενο στο σωρό, θα είναι κατάλληλη για συλλογή απορριμμάτων.
Μόλις η μέθοδος m2 ολοκληρώσει την εκτέλεσή της. Θα βγει από τη στοίβα και όλη η μεταβλητή της θα ξεπλυθεί και δεν θα είναι πλέον διαθέσιμη για χρήση.
Το ίδιο και για τη μέθοδο m1.
Τελικά, η ροή ελέγχου θα επιστρέψει στο σημείο έναρξης του προγράμματος. Η οποία συνήθως είναι η «κύρια» μέθοδος.
Τι γίνεται αν το Αντικείμενο έχει μια αναφορά ως μεταβλητή παρουσίας του;
public static void main(String args[]) { A parent = new A(); //more code } class A{ B child = new B(); int e; //more code } class B{ int c; int d; //more code }
Σε αυτήν την περίπτωση, η μεταβλητή αναφοράς «παιδί» θα δημιουργηθεί σε σωρό, η οποία με τη σειρά της θα δείχνει προς το αντικείμενό της, κάτι σαν το διάγραμμα που φαίνεται παρακάτω.
Σε τι βρίσκεται το Garbage Collection Java?
Συλλογή σκουπιδιών σε Java είναι μια διαδικασία με την οποία τα προγράμματα εκτελούν αυτόματα διαχείριση μνήμης. Το Garbage Collector (GC) βρίσκει τα αχρησιμοποίητα αντικείμενα και τα διαγράφει για να ανακτήσει τη μνήμη. Σε Java, η δυναμική εκχώρηση μνήμης των αντικειμένων επιτυγχάνεται χρησιμοποιώντας τον νέο τελεστή που χρησιμοποιεί κάποια μνήμη και η μνήμη παραμένει εκχωρημένη μέχρι να υπάρξουν αναφορές για τη χρήση του αντικειμένου.
Όταν δεν υπάρχουν αναφορές σε ένα αντικείμενο, θεωρείται ότι δεν χρειάζεται πλέον και η μνήμη που καταλαμβάνεται από το αντικείμενο μπορεί να ανακτηθεί. Δεν υπάρχει ρητή ανάγκη να καταστρέψετε ένα αντικείμενο ως Java χειρίζεται αυτόματα την αποκατανομή.
Η τεχνική που το επιτυγχάνει είναι γνωστή ως Συλλογή απορριμάτων. Προγράμματα που δεν καταργούν την εκχώρηση μνήμης μπορεί τελικά να διακοπούν όταν δεν υπάρχει μνήμη στο σύστημα για εκχώρηση. Αυτά τα προγράμματα λέγεται ότι έχουν διαρροές μνήμης. Αποκομιδή σκουπιδιών σε Java συμβαίνει αυτόματα κατά τη διάρκεια ζωής του προγράμματος, εξαλείφοντας την ανάγκη αποδέσμευσης μνήμης και επομένως αποτρέποντας τις διαρροές μνήμης.
Στη γλώσσα C, είναι ευθύνη του προγραμματιστή να καταργήσει τη μνήμη που εκχωρείται δυναμικά χρησιμοποιώντας τη συνάρτηση free(). Εδώ είναι που Java απαγωγές διαχείρισης μνήμης.
Σημείωση: Όλα τα αντικείμενα δημιουργούνται στο Heap Section της μνήμης. Περισσότερα για αυτό σε επόμενο σεμινάριο.
Παράδειγμα: Για να μάθετε τον μηχανισμό συλλογής σκουπιδιών στο Java
Βήμα 1) Αντιγράψτε τον παρακάτω κώδικα σε ένα πρόγραμμα επεξεργασίας.
class Student{ int a; int b; public void setData(int c,int d){ a=c; b=d; } public void showData(){ System.out.println("Value of a = "+a); System.out.println("Value of b = "+b); } public static void main(String args[]){ Student s1 = new Student(); Student s2 = new Student(); s1.setData(1,2); s2.setData(3,4); s1.showData(); s2.showData(); //Student s3; //s3=s2; //s3.showData(); //s2=null; //s3.showData(); //s3=null; //s3.showData(); } }
Βήμα 2) Αποθηκεύστε, μεταγλωττίστε και εκτελέστε τον κώδικα. Όπως φαίνεται στο διάγραμμα, δημιουργούνται δύο αντικείμενα και δύο μεταβλητές αναφοράς.
Βήμα 3) Γραμμή μη σχολιασμού # 20,21,22. Αποθηκεύστε, μεταγλωττίστε και εκτελέστε τον κώδικα.
Βήμα 4) Όπως φαίνεται στο παρακάτω διάγραμμα, δύο μεταβλητές αναφοράς δείχνουν προς το ίδιο αντικείμενο.
Βήμα 5) Κατάργηση σχολίου γραμμή # 23 & 24. Μεταγλώττιση, αποθήκευση και εκτέλεση του κώδικα
Βήμα 6) Όπως φαίνεται στο παρακάτω διάγραμμα, το s2 γίνεται μηδενικό, αλλά το s3 εξακολουθεί να δείχνει προς το αντικείμενο και δεν είναι κατάλληλο για συλλογή σκουπιδιών java.
Βήμα 7) Από τη γραμμή σχολίων # 25 & 26. Αποθηκεύστε, μεταγλωττίστε και εκτελέστε τον κώδικα
Βήμα 8) Σε αυτό το σημείο δεν υπάρχουν αναφορές που να δείχνουν το αντικείμενο και καθίσταται επιλέξιμο για αποκομιδή σκουπιδιών. Θα αφαιρεθεί από τη μνήμη και δεν υπάρχει τρόπος να το ανακτήσετε ξανά.
Πώς να διαγράψετε ένα αντικείμενο σε Java?
1) Εάν θέλετε να κάνετε το αντικείμενό σας κατάλληλο για Συλλογή σκουπιδιών, αντιστοιχίστε τη μεταβλητή αναφοράς του σε null.
2) Οι πρωτόγονοι τύποι δεν είναι αντικείμενα. Δεν μπορούν να οριστούν μηδενικά.
Περίληψη:
- Όταν καλείται μια μέθοδος, δημιουργείται ένα πλαίσιο στο επάνω μέρος της στοίβας.
- Μόλις μια μέθοδος ολοκληρώσει την εκτέλεση, η ροή του ελέγχου επιστρέφει στη μέθοδο κλήσης και το αντίστοιχο πλαίσιο στοίβας ξεπλένεται.
- Οι τοπικές μεταβλητές δημιουργούνται στη στοίβα
- Οι μεταβλητές παράδειγμα δημιουργούνται στο σωρό και αποτελούν μέρος του αντικειμένου στο οποίο ανήκουν.
- Οι μεταβλητές αναφοράς δημιουργούνται στη στοίβα.