Κατέβασμα παρουσίασης
Η παρουσίαση φορτώνεται. Παρακαλείστε να περιμένετε
1
Εισαγωγή στον Προγ/μό Η/Υ
Ενότητα 8: Αντικείμενα και Μνήμη Διδάσκων: Μιχάλης Τίτσιας
2
Περιεχόμενα Η δομή της μνήμης Η εκχώρηση μνήμης στις μεταβλητές
Αρχέγονοι τύποι και αντικείμενα Συνδέοντας αντικείμενα μεταξύ τους
3
Δυαδική μορφή Τα Bytes και τα words μπορούν να χρησιμοποιηθούν για να αντιπροσωπεύσουν ακέραιους διαφορετικών μεγεθών με την ερμηνεία των bits ως αριθμό σε δυαδική μορφή. H δυαδική είναι παρόμοια με την δεκαδική μορφή, αλλά χρησιμοποιεί διαφορετική βάση. Οι δεκαδικοί αριθμοί έχουν το 10 ως βάση, που σημαίνει ότι κάθε ψηφίο αξίζει δέκα φορές όσο το ψηφίο στα δεξιά του. Η Δυαδική χρησιμοποιεί βάση 2, που σημαίνει ότι κάθε θέση αξίζει το διπλάσιο: 1 0 x = 128 0 x = 64 1 x = 32 0 x = 16 1 x = 8 0 x = 1 Και ούτω καθεξής. . Το επόμενο δίνει τον αριθμό των 4. Το επόμενο δίνει τον αριθμό των 2. Το δεξιότερο ψηφίο είναι η μονάδα. 1 x = 2 0 x = 4 42
4
Η δομή της μνήμης Η θεμελιώδης μονάδα της μνήμης σε έναν υπολογιστή ονομάζεται bit, το οποίο είναι μια σύντμηση του binary digit. Ένα bit μπορεί να είναι σε μια από δύο καταστάσεις, που συνήθως συμβολίζονται με 0 και 1. 1 Η δομή του υλικού του υπολογιστή συνδυάζει επιμέρους bits σε μεγαλύτερες μονάδες. Στις περισσότερες αρχιτεκτονικές, η μικρότερη μονάδα είναι μια ακολουθία οκτώ διαδοχικών δυαδικών ψηφίων που ονομάζεται byte. Το παρακάτω διάγραμμα δείχνει ένα byte που περιέχει ένα συνδυασμό από 0 και 1: Οι αριθμοί αποθηκεύονται σε ακόμα μεγαλύτερες μονάδες που αποτελούνται από πολλαπλά bytes. Η μονάδα που αντιπροσωπεύει το πιο κοινό ακέραιο μέγεθος για ένα συγκεκριμένο υλικό ονομάζεται word. Επειδή οι μηχανές έχουν διαφορετικές αρχιτεκτονικές, ο αριθμός των bytes σε ένα word μπορεί να διαφέρει από μηχανή σε μηχανή.
5
Αριθμοί και Βάσεις Ο υπολογισμός στο τέλος της προηγούμενης διαφάνειας δείχνει ότι η δυαδική αναπαράσταση είναι ισοδύναμη με τον αριθμό 42. Όταν χρειάζεται να γίνει διάκριση της βάσης, θα χρησιμοποιούμε ένα μικρό δείκτη, όπως εδώ : = 4210 Αν και είναι χρήσιμο να μπορείτε να μετατρέψετε έναν αριθμό από τη μία βάση σε άλλη, είναι σημαντικό να θυμάστε ότι ο αριθμός είναι ο ίδιος. Αυτό που αλλάζει είναι το πώς γράφεται. Ο αριθμός 42 είναι αυτό που θα βρείτε αν μετρήστε τα αστέρια στα δεξιά. Ο αριθμός είναι ο ίδιος αν θα το γράψετε ως σαράντα δύο, ή ως 42, ή ως Οι αριθμοί δεν έχουν βάσεις. Οι αναπαραστάσεις τους έχουν.
6
Οκταδική και δεκαεξαδική γραφή
Επειδή η δυαδική μορφή τείνει να είναι αρκετά μακριά, οι Πληροφορικοι προτιμούν συχνά οκταδικούς (βάση 8) ή δεκαεξαδικούς (βάση 16) συμβολισμούς. Η οκταδική γραφή χρησιμοποιεί οκτώ ψηφία: 0 έως 7. Η Δεκαεξαδική γραφή χρησιμοποιεί δεκαέξι ψηφία: 0 έως 9, ακολουθούμενο από τα γράμματα Α έως F για τις τιμές 10 έως 15. Τα παρακάτω διαγράμματα δείχνουν τον αριθμό σαράντα δύο σε οκταδική και δεκαεξαδική γραφή: 2 x = 2 1 5 x 40 8 5 42 10 x 10 02 x 32 16 A οκταδική δεκαεξαδική Το πλεονέκτημα της χρήσης οκταδικής ή δεκαεξαδικής γραφής είναι ότι είναι εύκολο να μεταφράσουμε τον αριθμό σε bits, επειδή μπορείτε να μετατρέψετε κάθε ψηφίο χωριστά.
7
Ασκήσεις: Βάσεις Αριθμών
Ποια είναι η δεκαδική τιμή κάθε ενός από τους αριθμούς? 100012 1778 AD16 1 x = 1 0 x 2 4 8 16 17 17 7 x = 7 1 56 8 127 1 x 64 127 173 13 x = 13 1 10 x 160 16 A D 173 Ως μέρος του κώδικα προσδιορισμού του τύπου αρχείου, κάθε εκτελέσιμο αρχείο Java ξεκινά με αυτά τα δεκαέξι bits: 1 Πώς θα γραφόταν ο αριθμός στο δεκαεξαδικό σύστημα? 1 A F E CAFE16
8
Μνήμη και Διευθύνσεις Κάθε byte στην μνήμη ενός Η/Υ προσδιορίζεται από μια αριθμητική διεύθυνση. Οι διευθύνσεις αρχίζουν στις 0 και εκτείνονται μέχρι τον αριθμό των διαθέσιμων bytes, όπως φαίνεται δεξιά. 0000 0004 0008 000C 0010 0014 0018 001C 0020 0024 0028 002C FFD0 FFD4 FFD8 FFDC FFE0 FFE4 FFE8 FFEC FFF0 FFF4 FFF8 FFFC 0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B FFF4 FFF5 FFF6 FFF7 FFF8 FFF9 FFFA FFFB FFFC FFFD FFFE FFFF Σε αυτές τις διαφάνειες, οι διευθύνσεις μνήμης εμφανίζονται ως τετραψήφιοι δεκαεξαδικοί αριθμοί, που τις κάνει εύκολα αναγνωρίσιμες. . . Στη Java, είναι αδύνατο να προσδιοριστεί η διεύθυνση ενός αντικειμένου. Οι διευθύνσεις μνήμης που χρησιμοποιούνται στα παραδείγματα έχουν ως εκ τούτου επιλεγεί αυθαίρετα. Διαγράμματα μνήμης από επιμέρους bytes δεν είναι τόσο χρήσιμα όσο αυτά που είναι οργανωμένα σε λέξεις. Το αναθεωρημένο διάγραμμα στα δεξιά περιλαμβάνει τώρα τέσσερα bytes σε κάθε κύτταρο μνήμης, που σημαίνει ότι οι αριθμοί διευθύνσεων αυξάνονται κατά τέσσερα κάθε φορά.
9
Η εκχώρηση μνήμης στις μεταβλητές
Όταν δηλώνετε μια μεταβλητή σε ένα πρόγραμμα, η Java διαθέτει χώρο για την εν λόγω μεταβλητή από μία από τις πολλές περιοχές μνήμης. Μία περιοχή μνήμης δεσμεύεται για μεταβλητές που δεν δημιουργούνται ή καταστρέφονται ποτέ όσο τρέχει ένα πρόγραμμα, όπως οι σταθερές και άλλες μεταβλητές τάξεων. Αυτές οι πληροφορίες ονομάζονται στατικά δεδομένα. στατικά δεδομένα 0000 Όποτε δημιουργείτε ένα νέο αντικείμενο, η Java διαθέτει χώρο από τον σωρό. σωρός Στις κλασσικές αρχιτεκτονικές, στοίβα και σωρός μεγαλώνουν το ένα προς το άλλο για τη μεγιστοποίηση του διαθέσιμου χώρου. στοίβα\ FFFF Κάθε φορά που θα καλείτε μια μέθοδο, η Java διαθέτει ένα νέο μπλοκ μνήμης που ονομάζεται πλαίσιο στοίβας για να κρατήσει τις τοπικές μεταβλητές. Αυτά δημιουργούνται σε μια περιοχή της μνήμης που ονομάζεται στοίβα.
10
Διαγράμματα σωρού-στοίβας
Είναι πιο εύκολο να καταλάβετε πώς λειτουργεί η Java, αν έχετε ένα καλό νοητικό μοντέλο της χρήσης μνήμης της. Τα διαγράμματα σωρού-στοίβας δείχνουν τον σωρό στα αριστερά και τη στοίβα στα δεξιά, και χωρίζονται με μια διακεκομμένη γραμμή. Όταν το πρόγραμμα σας δημιουργεί ένα νέο αντικείμενο, θα πρέπει να προσθέτετε ένα μπλοκ μνήμης στην πλευρά του σωρού. Το μπλοκ πρέπει να είναι αρκετά μεγάλο για να αποθηκεύσει τις μεταβλητές του, μαζί με κάποιο επιπλέον χώρο, που ονομάζεται overhead, και απαιτείται για κάθε αντικείμενο. Ο overhead χώρος στα διαγράμματα συμβολίζεται ως εγχάρακτο κουτί Όταν το πρόγραμμά σας καλεί μια μέθοδο, θα πρέπει να δημιουργήσετε ένα νέο πλαίσιο στοίβας σε ενός μπλοκ μνήμης την πλευρά της στοίβας. Αυτό θα πρέπει να έχει αρκετό χώρο για να αποθηκεύσει τις τοπικές μεταβλητές μαζί με κάποια στοιχεία για την κατάσταση του προγράμματος. Όταν μια μέθοδος επιστρέφει, η Java διεκδικεί πίσω τη μνήμη
11
Αναφορές σε αντικείμενα
Εσωτερικά, η Java προσδιορίζει ένα αντικείμενο από τη διεύθυνσή του στη μνήμη. Αυτή η διεύθυνση ονομάζεται αναφορά Rational r1 = new Rational(1, 2); heap 2 den 1 num 1008 1004 1000 διαθέτει χώρο στον σωρό (heap) για ένα νέο αντικείμενο Rational. Για παράδειγμα, θεωρείστε ότι το αντικείμενο έχει δημιουργηθεί στη διεύθυνση 1000. Π.χ. όταν Java αξιολογεί τη δήλωση stack 1000 r1 FFFC Η τοπική μεταβλητή r1 κατανέμεται στο τρέχον πλαίσιο στοίβας (stack) και της αποδίδεται η τιμή 1000, που προσδιορίζει το αντικείμενο. Η επόμενη διαφάνεια δείχνει την εκτέλεση του προγράμματος TestRational που είδαμε σε προηγούμενη ενότητα με την χρήση διαγράμματος σωρού-στοίβας.
12
Ένα πλήρες διάγραμμα Heap-Stack
TestRational 1/2 + 1/3 + 1/6 = 1 public void run() { Rational a = new Rational(1, 2); Rational b = new Rational(1, 3); Rational c = new Rational(1, 6); Rational sum = a.add(b).add(c); println(a + " + " + b + " + " + c + " = " + sum); } 1 den num 6 5 3 2 heap stack a b c sum FFFC FFF8 FFF4 FFF0 FFEC 1000 100C 1018 1030 1038 1034 102C 1028 1024 1020 101C 1014 1010 1008 1004 public void run() { Rational a = new Rational(1, 2); Rational b = new Rational(1, 3); Rational c = new Rational(1, 6); Rational sum = a.add(b).add(c); println(a + " + " + b + " + " + c + " = " + sum); } public Rational add(Rational r) { return new Rational( this.num * r.den + r.num * this.den , this.den * r.den ); } public Rational add(Rational r) { return new Rational( this.num * r.den + r.num * this.den , this.den * r.den ); } 36 5 1 3 1 2 6 36 heap stack TestRational 2 den 1 num Όλα τα αντικείμενα δημιουργούνται στο σωρό. 1008 1004 1000 1/2 + 1/3 + 1/6 = 1 3 den 1 num 1014 1010 100C 6 den 1 num Προσωρινό αντικείμενο που χρησιμοποιείται μόνο κατά τη διάρκεια του υπολογισμού 1020 101C 1018 1000 100C this r FFE8 FFE4 FFE0 Αυτό το πλαίσιο στοίβας Δημιουργείται για την add. 100C 1018 1000 1024 6 den 5 num 102C 1028 1024 a b c sum FFFC FFF8 FFF4 FFF0 FFEC Αυτό το πλαίσιο στοίβας Δημιουργείται για την run. 1030 1018 1 den num 1038 1034 1030 100C 1000 skip simulation
13
Το μοντέλο δεικτών Το διάγραμμα σωρού-στοίβας κάτω αριστερά δείχνει την κατάσταση της μνήμης στο τέλος της TestRational. Το διάγραμμα κάτω δεξιά δείχνει ακριβώς την ίδια κατάσταση χρησιμοποιώντας βέλη αντί για αριθμητικές διευθύνσεις. Αυτό το διάγραμμα λέγεται ότι χρησιμοποιεί το μοντέλο δείκτών. 1 den num 6 5 3 2 a b c sum heap stack heap stack 2 den 1 num 1008 1004 1000 3 den 1 num 1014 1010 100C 6 den 1 num 1020 101C 1018 6 den 5 num 102C 1028 1024 a b c sum FFFC FFF8 FFF4 FFF0 FFEC 1030 1018 1 den num 1038 1034 1030 100C 1000
14
Διευθύνσεις και Δείκτες
Οι δύο τύποι διαγραμμάτων σωρού-στοίβας (τα μοντέλα διευθύνσεων και δεικτών) περιγράφουν ακριβώς την ίδια κατάσταση μνήμης. Τα μοντέλα, ωστόσο, τονίζουν διαφορετικά πράγματα:: Το μοντέλο διευθύνσεων, ότι οι αναφορές έχουν αριθμητικές τιμές. Το μοντέλο δείκτη τη σχέση μεταξύ της αναφοράς και αντικειμένου κάνοντας το διάγραμμα πιο εύκολο να διαβαστεί. 1 den num 6 5 3 2 heap stack a b c sum FFFC FFF8 FFF4 FFF0 FFEC 1000 100C 1018 1030 1038 1034 102C 1028 1024 1020 101C 1014 1010 1008 1004 1 den num 6 5 3 2 a b c sum heap stack
15
Συλλογή Απορριμμάτων Ένα γεγονός που το μοντέλο δείκτη καθιστά σαφές είναι ότι δεν υπάρχουν πλέον αναφορές στην Rational τιμή 5/6. Η τιμή αυτή έχει γίνει πλέον απόρριμμα. Από καιρό σε καιρό η Java περνά μέσα από το σωρό για να απελευθερώνει τα απορρίμματα. Αυτή η διαδικασία ονομάζεται συλλογή απορριμμάτων. heap stack 2 den 1 num 3 den 1 num 6 den 1 num Το αντικείμενο αυτό χρησιμοποιήθηκε για να κρατήσει μια προσωρινή μεταβλητή και δεν είναι πλέον προσβάσιμο. 6 den 5 num sum c 1 den num b a
16
Άσκηση: διαγράμματα σωρού-στοίβας
Υποθέστε ότι οι τάξεις Point και Line ορίζονται ως εξής: public class Point { public Point(int x, int y) { cx = x; cy = y; } . . . other methods appear here . . . private int cx; private int cy; public class Line { public Line(Point p1, Point p2) { start = p1; finish = p2; } . . . other methods appear here . . . private Point start; private Point finish; Σχεδιάστε ένα διάγραμμα σωρού-στοίβας που να δείχνει την κατάσταση της μνήμης ακριβώς πριν η μέθοδος run επιστρέψει public void run() { Point p1 = new Point(0, 0); Point p2 = new Point(200, 200); Line line = new Line(p1, p2); }
17
Λύση: διαγράμματα σωρού-στοίβας
Address Model Pointer Model 100C finish 1000 start 200 cy cx heap stack p1 p2 line FFFC FFF8 FFF4 FFF0 1018 1020 101C 1014 1010 1008 1004 finish start 200 cy cx p1 p2 line heap stack
18
Αρχέγονοι τύποι και αντικείμενα
Με την πρώτη ματιά, οι κανόνες της Java για την χρήση αντικείμενων ως ορίσματα φαίνεται να διαφέρουν από τους κανόνες για ορίσματα που είναι αρχέγονοι τύποι Όταν περνάτε ένα όρισμα αρχέγονου τύπου σε μια μέθοδο, η Java αντιγράφει την τιμή του σε μια τοπική μεταβλητή εντός της μεθόδου. Ως αποτέλεσμα, οι αλλαγές στην αντιγραμμένη μεταβλητή δεν έχουν καμία επίδραση στο όρισμα Όταν όμως περνάτε ένα αντικείμενο ως όρισμα τότε ουσιαστικά περνάτε την διεύθυνση που δείχνει στις μεταβλητές του αντικειμένου και όχι το ίδιο το αντικείμενο (η διεύθυνση είναι αυτή που αντιγράφεται). Επομένως αλλαγές που κάνετε στις μεταβλητές (μέσω της διεύθυνσης), έχουν μόνιμη επίδραση στις μεταβλητές του αντικείμενου Τα διαγράμματα σωρού-στοίβας κάνουν τον λόγο για αυτή τη φαινομενική ασυμμετρία σαφή. Όταν περνάτε ένα αντικείμενο σε μια μέθοδο η Java αντιγράφει την διεύθυνση/αναφορά, αλλά όχι το ίδιο το αντικείμενο.
19
Παράδειγμα «κοινοκτημοσύνης» των αντικειμένων
public void run() { Counter c1 = new Counter(10); Counter c2 = new Counter(); println(c1.value); println(c2.value); c2 = c1; c1.increase(); } Η τελευταία εντολή println(c2.value)θα τυπώσει 12 και όχι 10!
20
Wrapper Τάξεις Οι σχεδιαστές της Java επέλεξαν να διαχωρίσουν τους αρχέγονους τύπους από την ιεραρχία κλάσεων για λόγους αποδοτικότητας. Οι αρχέγονοι τύποι πιάνουν λιγότερο χώρο και επιτρέπουν στην Java να χρησιμοποιεί περισσότερο τις δυνατότητες που παρέχονται από το υλικό. Ακόμα κι έτσι, υπάρχουν στιγμές όπου το ότι οι αρχέγονοι τύποι δεν είναι αντικείμενα είναι εμπόδιο. Υπάρχουν πολλά εργαλεία στις βιβλιοθήκες της Java, που λειτουργούν μόνο με αντικείμενα. Για να ξεπεράσει αυτό το πρόβλημα, η Java περιλαμβάνει μια κατηγορία wrapper τάξεων που αντιστοιχούν σε καθένα από τους αρχέγονους τύπους : boolean Boolean byte Byte char Character double Double float Float int Integer long Long short Short
21
Χρησιμοποιώντας Wrapper τάξεις
Integer five = new Integer(5); δημιουργεί ένα αντικείμενο Integer που περιέχει την τιμή 5: heap stack 1000 5 1004 five 1000 FFFC Η αποθηκευμένη στη μεταβλητή five τιμή είναι αντικείμενο, και μπορείτε να το χρησιμοποιήσετε οπουδήποτε απαιτούνται αντικείμενα. Για καθεμία από τις wrapper κλάσεις, η Java καθορίζει μια μέθοδο για να ανακτά την αρχέγονη αξία, όπως παρακάτω : int underlyingValue = five.intValue();
22
Boxing και Unboxing Από την έκδοση 5.0 η Java μετατρέπει αυτόματα τις τιμές ανάμεσα σε ένα αρχέγονο τύπο και την αντίστοιχη τάξη. Για παράδειγμα, εάν γράψετε: Integer five = 5; Η Java θα καλέσει αυτόματα τον κατασκευαστή Integer. Ομοίως, αν στη συνέχεια γράψετε int six = five + 1; η Java θα καλέσει την intValue πριν την πρόσθεση Αυτές οι λειτουργίες ονομάζονται boxing και unboxing. Παρά το γεγονός ότι τα boxing and unboxing μπορεί να είναι βολικά, τα χαρακτηριστικά αυτά μπορεί να δημιουργήσουν σύγχυση και θα πρέπει να χρησιμοποιούνται με προσοχή.
23
Συνδέοντας μαζί αντικείμενα
Oι αναφορές είναι ιδιαίτερα σημαντικές στην επιστήμη των υπολογιστών, επειδή επιτρέπουν την αποτύπωση σχέσεων μεταξύ αντικειμένων μέσω της σύνδεσής τους με διάφορους τρόπους. link data Ένα σύνηθες παράδειγμα ονομάζεται συνδεδεμένη λίστα, όπου κάθε αντικείμενο έχει μια αναφορά σε εκείνο που το ακολουθεί : null H Java σηματοδοτεί το τέλος της λίστας με τη σταθερά null, η οποία σηματοδοτεί μια αναφορά που δεν οδηγεί σε ένα πραγματικό αντικείμενο.
24
Οι φάροι της Gondor Απαντώντας ο Gandalf φώναξε δυνατά στο άλογό του. "Πάμε, Shadowfax! Πρέπει να επιταχύνουμε. Ο χρόνος είναι περιορισμένος. Δες! Οι φάροι της Gondor είναι αναμμένοι ζητώντας βοήθεια. Ο Πόλεμος έχει ανάψει. Βλέπε, υπάρχει φωτιά στο Amon Dîn, και φλόγα στο Eilenach; Και πηγαίνουν δυτικά: Nardol, Erelas, Min-Rimmon, Calenhad, και Halifirien στα σύνορα του Rohan.” —J. R. R. Tolkien, The Return of the King, 1955 Σε μια σκηνή στην «Επιστροφή του βασιλιά», η Rohan μαθαίνει για τον κίνδυνο στην Gondor από μια σειρά φάρων που ανάβουν στις κορυφές των βουνών. Αυτή η σκηνή είναι ένα τέλειο παράδειγμα της ανταλλαγής μηνυμάτων σε μια συνδεδεμένη λίστα. Minas Tirith Amon Dîn Eilenach Nardol Erelas Min-Rimmon Calenhad Halifirien Rohan
25
T.signal(); Για να εκφράσετε αυτήν την εικόνα, μπορείτε να χρησιμοποιήσετε έναν ορισμό όπως αυτός στα δεξιά. public class SignalTower { /* Constructs a new signal tower */ public SignalTower(String name, SignalTower link) { towerName = name; nextTower = link; } /* * Signals this tower and passes the * message along to the next one. */ public void signal() { lightCurrentTower(); if (nextTower != null) { nextTower.signal(); /* Marks this tower as lit */ public void lightCurrentTower() { . . . code to draw a fire on this tower . . . /* Private instance variables */ private String towerName; private SignalTower nextTower; Μπορείτε να αρχικοποιήσετε μια αλυσίδα SignalTower, έτσι Minas Tirith Min-Rimmon Amon Dîn Calenhad Eilenach Halifirien Nardol Rohan null Erelas Καλώντας την signal στον πρώτο πύργο στέλνετε το μήνυμα μέσω της αλυσίδας.
26
Διάβασμα για το σπίτι Κεφάλαιο 7 από «Η Τέχνη και Επιστήμη της JAVA: Μια εισαγωγή στην Επιστήμη των Υπολογιστών», E. Roberts
Παρόμοιες παρουσιάσεις
© 2024 SlidePlayer.gr Inc.
All rights reserved.