User Tools

Site Tools


java:thread_memory_model

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
java:thread_memory_model [2017/03/18 14:01] – [Το μοντέλο μνήμης της Java] gthanosjava:thread_memory_model [2018/03/08 09:31] (current) – [Στατικές μεταβλητές της κλάσης] gthanos
Line 17: Line 17:
 Το μοντέλο μνήμης στην Java δίνεται από το παρακάτω σχήμα. Κάθε νήμα διαθέτει την δική του στοίβα (stack), όπου αποθηκεύονται οι τιμές των τοπικών μεταβλητών. Κάθε νήμα έχει πρόσβαση αποκλειστικά στην δική του στοίβα, χωρίς δυνατότητα πρόσβασης στις στοίβες άλλων νημάτων. Παράλληλα υπάρχει και ο κοινός χώρος αποθήκευσης δεδομένων (το λεγόμενο Heap), όπου αποθηκεύονται όλα τα αντικείμενα που δημιουργούνται κατά την εκτέλεση του προγράμματος.  Το μοντέλο μνήμης στην Java δίνεται από το παρακάτω σχήμα. Κάθε νήμα διαθέτει την δική του στοίβα (stack), όπου αποθηκεύονται οι τιμές των τοπικών μεταβλητών. Κάθε νήμα έχει πρόσβαση αποκλειστικά στην δική του στοίβα, χωρίς δυνατότητα πρόσβασης στις στοίβες άλλων νημάτων. Παράλληλα υπάρχει και ο κοινός χώρος αποθήκευσης δεδομένων (το λεγόμενο Heap), όπου αποθηκεύονται όλα τα αντικείμενα που δημιουργούνται κατά την εκτέλεση του προγράμματος. 
  
-{{:java:java-memory-model-1.png?400 | }} Το διπλανό σχήμα αποτυπώνει το βασικό μοντέλο μνήμης. Διακρίνονται το stack όπου αποθηκεύονται οι τοπικές μεταβλητές των μεθόδων που εκτελούνται από κάθε νήμα και το Heap που αποθηκεύονται τα αντικείμενα που δημιουργούνται από όλα τα νήματα.+{{  :java:thread_stack_heap.png?400 | Το σχήμα αποτυπώνει το βασικό μοντέλο μνήμης. Διακρίνονται το stack όπου αποθηκεύονται οι τοπικές μεταβλητές των μεθόδων που εκτελούνται από κάθε νήμα και το Heap που αποθηκεύονται τα αντικείμενα που δημιουργούνται από όλα τα νήματα. }} 
  
 ===== Το μοντέλο μνήμης των μεταβλητών ===== ===== Το μοντέλο μνήμης των μεταβλητών =====
  
-==== Μεταβλητές ως παράμετροι συναρτήσεων ====+==== Μεταβλητές ως παράμετροι μεθόδων ====
  
-=== Βασικοί τύποι δεδομένων ως παράμετροι συναρτήσεων ===+=== Βασικοί τύποι δεδομένων ως παράμετροι μεθόδων ===
  
-Κάθε τοπική μεταβλητή αποθηκεύεται στο stack. Για τις τοπικές μεταβλητές βασικού τύπου (//int, byte, long, double//) που γνωρίζουμε εκ των προτέρων το μήκος τους αυτές αποθηκεύονται στη στοίβα. Στο παρακάτω παράδειγμα, έχουμε τις μεταβλητές //a, b, c//. Και οι τρεις μεταβλητές είναι τοπικές δημιουργούνται στην στοίβα του νήματος και καταστρέφονται μετά από την εκτέλεση της μεθόδου //add// Κανένα άλλο νήμα δεν μπορεί να έχει πρόσβαση σε τοπικές μεταβλητές βασικού τύπου.+Κάθε τοπική μεταβλητή αποθηκεύεται στη στοίβα (//stack//). Για τις τοπικές μεταβλητές βασικού τύπου (//int, byte, long, double//) που γνωρίζουμε εκ των προτέρων το μέγεθος τους αυτές αποθηκεύονται στη στοίβα. Στο παρακάτω παράδειγμα, έχουμε τις μεταβλητές //a, b, c//. Και οι τρεις μεταβλητές είναι τοπικές δημιουργούνται στην στοίβα του νήματος και καταστρέφονται μετά από την εκτέλεση της μεθόδου //add// Κανένα άλλο νήμα δεν μπορεί να έχει πρόσβαση σε τοπικές μεταβλητές βασικού τύπου.
 <code java> <code java>
   int add(int a, int b) {   int add(int a, int b) {
Line 33: Line 33:
 </code> </code>
  
-=== Αναφορικοί τύποι δεδομένων ως παράμετροι συναρτήσεων ===+=== Αναφορικοί τύποι δεδομένων ως παράμετροι μεθόδων ===
  
 Όταν δημιουργείται ένα αντικείμενο το οποίο ανατίθεται σε μία τοπική μεταβλητή ενός νήματος, τότε η τοπική μεταβλητή παρέχει μία αναφορά προς το αντικείμενο αυτό. Η τοπική μεταβλητή είναι αποθηκευμένη στο //stack//, αλλά το αντικείμενο στο οποίο δείχνει η μεταβλητή είναι αποθηκευμένο στο //heap//. Στο παρακάτω παράδειγμα, οι μεταβλητές //a, b, sum, referenceSum// είναι τοπικές. Οι //a, b, referenceSum// όμως δείχνουν σε αντικείμενα τύπου //Integer// τα οποία είναι αποθηκευμένα στο Heap. Η ζωή των αντικειμένων αυτών εξαρτάται από το κατά πόσο εξακολουθούν να υπάρχουν αναφορές προς αυτά από τοπικές μεταβλητές ή πεδία αντικειμένων ή στατικές μεταβλητές. Όταν δημιουργείται ένα αντικείμενο το οποίο ανατίθεται σε μία τοπική μεταβλητή ενός νήματος, τότε η τοπική μεταβλητή παρέχει μία αναφορά προς το αντικείμενο αυτό. Η τοπική μεταβλητή είναι αποθηκευμένη στο //stack//, αλλά το αντικείμενο στο οποίο δείχνει η μεταβλητή είναι αποθηκευμένο στο //heap//. Στο παρακάτω παράδειγμα, οι μεταβλητές //a, b, sum, referenceSum// είναι τοπικές. Οι //a, b, referenceSum// όμως δείχνουν σε αντικείμενα τύπου //Integer// τα οποία είναι αποθηκευμένα στο Heap. Η ζωή των αντικειμένων αυτών εξαρτάται από το κατά πόσο εξακολουθούν να υπάρχουν αναφορές προς αυτά από τοπικές μεταβλητές ή πεδία αντικειμένων ή στατικές μεταβλητές.
  
-Αντικείμενα που είναι αποθηκευμένα στο //heap// είναι δυνατόν να διαμοιράζονται με άλλα νήματα.+<WRAP tip 80% center round> 
 +Αντικείμενα που είναι αποθηκευμένα στο //heap// είναι δυνατόν να διαμοιράζονται με άλλα νήματα ανεξάρτητα από την τοπικότητα ή μη των μεταβλητών που δείχνουν σε αυτά. 
 +</WRAP>
  
 <code java> <code java>
Line 48: Line 50:
  
  
-==== Μεταβλητές ως πεδία της κλάσης που υλοποιεί το νήμα ====+==== Μεταβλητές ως πεδία της κλάσης που υλοποιεί ένα νήμα ====
  
-Κάθε κλάση που υλοποιεί ένα νήμα (implements Runnable ή extends Thread) μπορεί να έχει πεδία βασικού ή αναφορικού τύπου. Οι μεταβλητές που είναι πεδία βασικού τύπου αν και αποθηκεύονται στο //heap// (μαζί με το αντικείμενο) είναι προσβάσιμες μόνο από το συγκεκριμένο νήμα. +Κάθε κλάση που υλοποιεί ένα νήμα (//implements Runnable// ή //extends Thread//) μπορεί να έχει πεδία βασικού ή αναφορικού τύπου. Οι μεταβλητές που είναι πεδία βασικού τύπου αν και αποθηκεύονται στο //heap// (μαζί με το αντικείμενο) είναι προσβάσιμες μόνο από το συγκεκριμένο νήμα. //Εξαίρεση αποτελεί εάν το συγκεκριμένο νήμα παρέχεται ως παράμετρος σε άλλα νήματα.//
  
-Αντίθετα, οι μεταβλητές που είναι αναφορικού τύπου παρά το γεγονός ότι είναι διαφορετικές για κάθε νήμα είναι δυνατόν να δείχνουν σε αντικείμενα που είναι κοινά με άλλα νήματα. Δείτε το παρακάτω παράδειγμα κώδικα, όπου τα δύο νήματα της κλάσης //BasicThread// διαμοιράζονται ένα αντικείμενο της κλάσης SharedObj.+Αντίθετα, μεταβλητές που είναι αναφορικού τύπου παρά το γεγονός ότι είναι διαφορετικές για κάθε νήμα είναι δυνατόν να δείχνουν σε αντικείμενα που είναι κοινά με άλλα νήματα. Δείτε το παρακάτω παράδειγμα κώδικα, όπου τα δύο νήματα της κλάσης //BasicThread// διαμοιράζονται ένα αντικείμενο της κλάσης //SharedObj//.
  
 <code java BasicThread.java> <code java BasicThread.java>
Line 58: Line 60:
      
   SharedObj shared;   SharedObj shared;
-  public BasicThread(SharedObj obj;) { shared = obj; }+  public BasicThread(SharedObj obj) { shared = obj; }
  
   public void run() {   public void run() {
Line 75: Line 77:
 class SharedObj { class SharedObj {
  
-  public Integer object2 = new Integer(22); +  public Integer object = new Integer(22); 
-  public Integer object4 new Integer(44);+  public long member 12345;
  
-  public long member1 = 12345; 
-  public long member2 = 67890; 
 } }
 </code> </code>
Line 85: Line 85:
 Παρακάτω δίνεται η σχηματική αναπαράσταση εκτέλεσης των δύο νημάτων της κλάσης //BasicThread//. Παρακάτω δίνεται η σχηματική αναπαράσταση εκτέλεσης των δύο νημάτων της κλάσης //BasicThread//.
  
-{{ :java:basic_thread_stack.png |}} +{{ :java:basic_thread_stack.png?500 |}}
- +
- +
-Συμπερασματικά: +
-  - Μία τοπική μεταβλητή βασικού τύπου (int, long, byte, double etc) αποθηκεύεται στο stack +
-  - Μία τοπική μεταβλητή ενός αναφορικού τόπου αποθηκεύει την αναφορά στο stack, αλλά το αντικείμενο στο heap. +
-  - Κάθε μέθοδος ενός αντικειμένου (που είναι αποθηκευμένο στο stack), εφόσον έχει τοπικές μεταβλητές αυτές αποθηκεύονται στο stack (ισχύουν τα παραπάνω για βασικούς και αναφορικούς τύπους). +
-  - Οι στατικές μεταβλητές ανήκουν στις κλάσεις τις οποίες ορίζονται κατά συνέπεια είναι αποθηκευμένες πάντοτε στο heap.+
  
 ===== Στατικές μεταβλητές της κλάσης ===== ===== Στατικές μεταβλητές της κλάσης =====
  
-Στο παρακάτω κώδικα δύο νήματα διαμοιράζονται μία τοπική μεταβλητή που δείχνει στο ίδιο στατικό πεδίο της κλάσης MySharedClass.+Στο παρακάτω κώδικα δύο νήματα της κλάσης //MyThread// διαμοιράζονται μέσω μίας τοπικής μεταβλητής το ίδιο στατικό πεδίο της κλάσης //SharedObj//. Καθώς το πεδίο είναι αναφορικού τύπου αποθηκεύεται στο //heap// και είναι προσβάσιμο και από τα δύο πεδία.
  
 <code java MyThread.java> <code java MyThread.java>
Line 103: Line 96:
   public void run() {   public void run() {
     int localInt = 45;     int localInt = 45;
-    MySharedClass localObj = MySharedClass.sharedInstance;    +    SharedObj localObj = SharedObj.sharedInstance; 
 +    localObj.member++;
   }   }
      
Line 112: Line 106:
 } }
  
-class MySharedClass { +class SharedObj {
- +
-  public static MySharedClass sharedInstance = new MySharedClass();+
  
-  public Integer object2 = new Integer(22); +  public static SharedObj sharedInstance = new SharedObj(); 
-  public Integer object4 = new Integer(44); +  public Integer object = new Integer(22); 
- +  public long member = 12345;
-  public long member1 = 12345+
-  public long member2 = 67890;+
 } }
 </code> </code>
  
-{{  :java:java-memory-model3.png?  }}+{{  :java:java-memory-model3.png?500  }} 
 + 
 +Στο παραπάνω διάγραμμα δίνεται σχηματικά η εκτέλεση του παραπάνω κώδικα. 
 + 
 +<WRAP tip 80% center round> 
 +=== Συμπερασματικά === 
 +  - Μία τοπική μεταβλητή βασικού τύπου (int, long, byte, double etc) αποθηκεύεται στο stack. 
 +  - Μία τοπική μεταβλητή ενός αναφορικού τόπου αποθηκεύει την αναφορά στο stack, αλλά το αντικείμενο στο heap. 
 +  - Οποιοδήποτε πεδίο της κλάσης ενός νήματος αποθηκεύεται στο heap μαζί με το αντικείμενο. Όλα τα πεδία  βασικού τύπου είναι προσβάσιμα μόνο από το νήμα. Όλα τα πεδία αναφορικού τύπου μπορούν να είναι προσβάσιμα από περισσότερα του ενός νήματα. 
 +  - Οι στατικές μεταβλητές ανήκουν στις κλάσεις τις οποίες ορίζονται κατά συνέπεια είναι αποθηκευμένες πάντοτε στο heap. 
 +</WRAP> 
 + 
 +|Προηγούμενο: [[:java:synchronization | Προβλήματα συγχρονισμού κατά την χρήση διαμοιραζόμενων πόρων  ]] | [[:toc | Περιεχόμενα ]] | Επόμενο: [[:java:synchronized_methods_blocks| Συγχρονισμένες μέθοδοι και blocks ]]|
  
-Στο παρακάτω σχηματικό διάγραμμα δίνεται σχηματικά η εκτέλεση του παραπάνω κώδικα, 
java/thread_memory_model.1489845670.txt.gz · Last modified: 2017/03/18 14:01 by gthanos