Δημοσιεύτηκε: 12 Σεπ 2008, 02:28
Το παρακάτω κείμενο δεν είναι δικής μου έμπνευσης,το έχει γράψει φίλος μου από άλλο forum.
Αν και μακροσκελές αξίζει να του ρίξετε μια ματιά.
Έχει τίτλο: Μνήμη στο Linux (ή "όχι,δεν τρώει τόση")
Αν ανοίξετε κάποιο memory monitor, το πρόγραμμα top ή δώσετε την εντολή free στην κονσόλα, πιθανότατα να δείτε μετά απο λίγα λεπτά χρήσης του υπολογιστή οτι η ελεύθερη μνήμη έχει κατέβει σε πολύ χαμηλά επίπεδα, ακόμα και αν έχετε 1gb μνήμης. Αν δείτε κάποια απο τα προγράμματα να τρέχουν, θα προσέξετε σε κάποιες στήλες να αναγράφονται ποσά του στυλ "600mb μνήμης" εδώ, και "500mb μνήμης" εκεί, κλπ.
Λογικό είναι να ταραχτείτε με την απορία: "μα πόση μνήμη θέλει τέλος πάντων;".
Ηρεμία. Δεν είναι τα πράγματα όπως φαίνονται.
Το Linux είναι ένα σύστημα φτιαγμένο απο πολλά μικρά αρχεία και πολλές βιβλιοθήκες οι οποίες βρίσκονται σε μορφή .so (shared object - κάτι σαν τα DLL των Windows). Επίσης οι ρυθμίσεις των διαφόρων προγραμμάτων βρίσκονται σε αρχεία κειμένου. Σχεδόν για κάθε πρόγραμμα που υπάρχει στο σύστημα (και μιλάμε για αρκετά προγράμματα - γράφοντας ls /{,usr/}{bin,sbin} | wc -l στην κονσόλα θα σας βγάλει τον αριθμό των περισσοτέρων προγραμμάτων που υπάρχουν εγκατεστημένα) υπάρχει κάπου και κάποιο configuration file (συνήθως στο /etc). Σε αυτά τα αρχεία, τα οποία πρέπει να εκτελούνται αρκετά συχνά αφού αρκετά κάνουν συγκεκριμένη δουλειά (πχ αν ανοίγετε ένα φάκελο απο το Nautilus του GNOME, το πρόγραμμα "file" εκτελείται για κάθε αρχείο ώστε να γνωρίζει ο Nautilus τι είδους αρχείο είναι αυτό, ενώ αν αποσυμπιέζετε ένα αρχείο .tar.gz, το GNOME file-roller καλεί το "tar" για να εξάγει τα αρχεία απο το archive, το οποίο με την σειρά του καλεί το gzip για να αποσυμπιέσει το archive, klp) προσθέστε και την περίπτωση το μηχάνημα να τρέχει σαν web ή database server όπου πολλά -συνήθως μικρά- αρχεία θα πρέπει να διαβάζονται συχνά και καταλήγετε στο συμπέρασμα οτι το Linux όλη την ώρα καλεί και διαβάζει απο τον δίσκο μικρά αρχεία.
Για να έχει καλύτερη απόδοση κάνοντας αυτές τις δουλειές, ο πυρήνας του Linux χρησιμοποιεί την αδέσμευτη μνήμη (την μνήμη που γενικότερα δεν χρησιμοποιείται απο τα προγράμματα) ώστε να σώσει δεδομένα που διαβάστηκαν πρόσφατα αρκετά συχνά απο τον δίσκο, ώστε την επόμενη φορά που θα ζητηθούν να βρίσκονται ήδη στην μνήμη, γλυτώνοντας το disk access το οποίο αφ'ενός θα ήταν πολύ πιο αργό και αφ'ετέρου θα μείωνε την ζωή του σκληρού δίσκου.
Αυτή η μνήμη είναι η λεγόμενη "cached μνήμη" του συστήματος.
Συχνά διάφορα προγράμματα εκτελούν άλλα με τα οποία χρειάζεται να επικοινωνούν (για παράδειγμα το "tar" εκτελεί το "gzip" για να αποσυμπιέσει ένα αρχείο .tar.gz). Επίσης συχνά κάποια προγράμματα έχουν διάφορα αρχεία ανοικτά για ένα χρονικό διάστημα (πχ όταν κάποιο αρχείο κατεβαίνει απο το Internet, το αρχείο στο οποίο σώζεται μένει ανοικτό για όλο το διάστημα του "κατεβάσματος").
Για την επικοινωνία μεταξύ των προγραμμάτων και γι'αυτά τα αρχεία (καθώς και για άλλα special αρχεία), ο πυρήνας δεσμεύει μνήμη ώστε να αποθηκεύει διάφορες πληροφορίες και τα κομμάτια των αρχείων που επεξεργάζεται. Αυτές η πληροφορίες σώζονται στους "buffers".
Έτσι πέρα απο την μνήμη που καταναλώνουν τα προγράμματα για τον εαυτό τους, υπάρχει και η cached μνήμη καθώς και η μνήμη που χρησιμοποιείται για τους buffers.
Αν ανοίξετε μια κονσόλα και γράψετε free -m θα δείτε τα διάφορα ποσά μνήμης σε megabytes (αν δεν δώσετε την παράμετρο -m θα δείτε τα ποσά σε kilobytes). Για παράδειγμα εγώ που έχω 512mb μνήμης, έχω τα παρακάτω αποτελέσματα:
Απο τα παραπάνω φαίνεται σαν η χρησιμοποιημένη μνήμη να είναι 189mb και η ελεύθερη να είναι 312mb (σημείωση: η συνολική μνήμη αναφέρεται σαν 502mb αντί για 512mb γιατί τα 10mb τα χρησιμοποιεί ο πυρήνας για τα δικά του δεδομένα).
Όμως όπως ανέφερα παραπάνω, η cached μνήμη που χρησιμοποιεί ο πυρήνας είναι ουσιαστικά αδέσμευτη μνήμη την οποία το σύστημα "δανείζεται". Αυτή η μνήμη απελευθερώνεται απο το σύστημα αν κάποιο πρόγραμμα την ζητήσει (δηλαδή δεν είναι "δεσμευμένη" απο κάποιο άλλο). Επίσης υπάρχουν και οι buffers οι οποίοι χρησιμοποιούνται για την μεταφορά δεδομένων μεταξύ προγραμμάτων ή για την χρήση διαφόρων αρχείων. Η μνήμη των buffers, όπως και η cached μνήμη, δεν είναι δεσμευμένη αλλά χρησιμοποιείται προσωρινά.
Έτσι ουσιαστικά η διαθέσιμη μνήμη του συστήματος περιλαμβάνει την ελεύθερη μνήμη, την cached μνήμη και την μνήμη που έχει κατανεμηθεί για τους buffers.
Με άλλα λόγια, η μνήμη που το σύστημα μου έχει διαθέσιμη είναι 416mb ενώ μόνο 85mb χρησιμοποιούνται απο τα προγράμματα. Αυτό φαίνεται με μια ματιά απο την μεσαία γραμμή:
HTML:
-/+ buffers/cache: 85 416
Ο πυρήνας του Linux προσπαθεί συνεχώς να χρησιμοποιεί το μεγαλύτερο μέρος της αδέσμευτης μνήμης για cache ώστε να επιτυγχάνεται μεγαλύτερη ταχύτητα στην προσπέλαση δεδομένων στον δίσκο. Αυτό το επιτυγχάνει τοποθετόντας τα δεδομένα των αρχείων που φορτώνονται ή γράφονται στην αδέσμευτη μνήμη μέχρι αυτά να διαγραφούν ή η cache να γεμίσει και να αντικατασταθούν με νεότερα δεδομένα ή κάποιο πρόγραμμα να χρειαστεί περισσότερη απο την ελεύθερη μνήμη.
Έτσι αν ανοίξετε κάποιο πρόγραμμα και χρησιμοποιήσετε δεδομένα 300mb μέσω του προγράμματος, τα δεδομένα αυτά δεν θα φύγουν απο την cached μνήμη όταν κλείσετε το πρόγραμμα (εκτός φυσικά κι αν γεμίσει η cache ή η μνήμη ζητηθεί απο κάποιο πρόγραμμα, όπως ανέφερα παραπάνω). Αυτό γίνεται γιατί μπορεί αυτά τα δεδομένα να ξαναχρησιμοποιηθούν σύντομα. Ο πυρήνας φροντίζει να χρησιμοποιήσει το μεγαλύτερο μέρος της αδέσμευτης μνήμης ως cache καθώς χρησιμοποιείτε αρχεία, αλλά πάντα αφήνει ένα σχετικά μικρό μέρος της μνήμης ελεύθερο. Ο λόγος γι'αυτό είναι οτι είναι γρηγορότερη η δέσμευση μνήμης απο την ελεύθερη περιοχή της μνήμης παρά απο την cached.
Ένα άλλο θέμα που ανέφερα στην αρχή είναι τα προγράμματα που καταβροχθίζουν μνήμη σε ρυθμούς μεγαλύτερους απο οτι οι ακρίδες καταβροχθίζουν τις φυτείες. Αλλά όπως και παραπάνω, το πρόβλημα είναι ουσιαστικά πλασματικό.
Όπως ανέφερα, το Linux αποτελείται απο πολλά προγράμματα και -το κυριότερο- βιβλιοθήκες σε μορφή shared objects. Επίσης, απο σχεδιασμού του λειτουργικού συστήματος, η πρόσβαση σε διάφορες συσκευές γίνεται μέσω της χρήσης ειδικών αρχείων τα οποία βρίσκονται στον κατάλογο /dev.
Όταν ένα πρόγραμμα τρέχει, χρησιμοποιεί κάποιες απο αυτές τις shared βιβλιοθήκες (με την κυριότερη να είναι η libc - ή αλλιώς c library - η οποία συνήθως βρίσκεται στο αρχείο /libc/libc.so.6) ενώ συχνά χρησιμοποιεί και κάποιες συσκευές (πχ κάρτα ήχου) μέσω των ειδικών τους αρχείων.
Η μνήμη που χρησιμοποιεί (επεξεργάζεται ή εκτελεί εντολές σε αυτήν μέσω της CPU) ένα πρόγραμμα χωρίζεται στις εξής κατηγορίες:
1. Την μνήμη που καταλαμβάνει ο κώδικας μηχανής του ίδιου του προγράμματος.
2. Την μνήμη που καταλαμβάνει ο κώδικας μηχανής των βιβλιοθηκών που χρησιμοποιεί το πρόγραμμα.
3. Την μνήμη που καταλαμβάνουν τα δεδομένα που επεξεργάζεται το πρόγραμμα.
4. Την μνήμη που καταλαμβάνουν τα δεδομένα που επεξεργάζονται οι βιβλιοθήκες που χρησιμοποιεί το πρόγραμμα και είναι αποκλειστικά για το πρόγραμμα.
5. Την μνήμη που καταλαμβάνουν τα δεδομένα που επεξεργάζονται οι βιβλιοθήκες που χρησιμοποιεί το πρόγραμμα και είναι κοινή για όλα τα προγράμματα που τις χρησιμοποιούν.
Εκτελώντας "ps aux" στην κονσόλα ώστε να δούμε πληροφορίες για την μνήμη που χρησιμοποιούν οι διάφορες διεργασίες (προγράμματα) που τρέχουν, βλέπουμε την εξής γραμμή για το Firefox (δεδομένου οτι το έχουμε ανοικτό :-Ρ):
HTML:
1000 2676 0.9 11.9 154636 61408 tty3 Sl 06:12& nbsp; 1:30 /usr/local/lib/firefox-2.0.0.3/firefox-bin
Το ενδιαφέρον είναι οι τιμές 154636 (έχει την επικεφαλίδα VSZ) και 61408 (έχει την επικεφαλίδα RSS). Αυτές δείχνουν την συνολική (154636kb) και εν χρήση (61408kb) μνήμη. Η διαφορά της συνολικής (virtual size) και εν χρήση (resident) είναι οτι η συνολική αναφέρεται γενικότερα στην μνήμη που χρησιμοποιεί το πρόγραμμα, συμπεριλαμβανομένων ανοικτών ή memory mapped αρχείων, συσκευών (πχ μνήμη στην κάρτα γραφικών), κ.α. ενώ η εν χρήση αναφέρεται στην φυσική μνήμη την οποία επεξεργάζεται το πρόγραμμα ή οι βιβλιοθήκες που χρησιμοποιεί.
Πριν όμως σκεφτείτε οτι το Firefox τρώει 150mb (ή 60mb) μνήμης σκεφτείτε πως, όπως αναφέρθηκε παραπάνω απο την free, όλο το σύστημα τρώει γύρω στα 85mb μνήμης. Και φυσικά δεν έχω ανοικτό μόνο το Firefox. Για την ακρίβεια, γράφοντας ps -A | wc -l για να μετρήσω τον αριθμό των processes, βλέπω οτι τρέχουν 63 processes (αυτό δεν σημαίνει οτι τρέχουν 63 προγράμματα, αλλά γενικότερα ο αριθμός των προγραμμάτων είναι σχετικά μεγάλος).
Πως είναι δυνατό αυτό όμως;
Είναι απλό. Η μνήμη στην οποία αναφέρεται το ps (όπως και τα περισσότερα προγράμματα τα οποία αναφέρουν την χρήση μνήμης - πχ το system monitor του GNOME), είναι η μνήμη την οποία χρησιμοποιεί το πρόγραμμα - αλλά όχι απαραίτητα μνήμη η οποία χρησιμοποιείται μόνο απο το πρόγραμμα!
Όπως ανέφερα παραπάνω, τα προγράμματα στο Linux χρησιμοποιούν πολλές βιβλιοθήκες σε μορφή shared objects. Αν δύο προγράμματα χρησιμοποιήσουν την ίδια βιβλιοθήκη, τότε ο κώδικας μηχανής της βιβλιοθήκης θα φορτωθεί στην μνήμη μόνο μια φορά. Το ίδιο ισχύει και για τις βιβλιοθήκες που χρησιμοποιούνται απο άλλες βιβλιοθήκες. Στην τελική, κάθε βιβλιοθήκη σε shared object μορφή, θα χρησιμοποιηθεί μόνο μια φορά.
Η σημαντικότερη βιβλιοθήκη του συστήματος είναι η libc. Αυτή προσφέρει τις βασικές λειτουργίες του συστήματος, όπως την διαχείρηση των αρχείων και της μνήμης. Αυτή η βιβλιοθήκη βρίσκεται στο /lib/libc.so.6 (ή .5 για παλιότερα συστήματα) και είναι -όπως δηλώνει η επέκταση της- ένα shared object, με αποτέλεσμα να φορτώνεται μόνο μια φορά και να χρησιμοποιείται απο όλα τα προγράμματα (με ελάχιστες εξαιρέσεις προγραμμάτων που κάνουν απευθείας κλήσεις στον πυρήνα ή έχουν την βιβλιοθήκη statically linked σε αυτά - αλλά αυτές οι περιπτώσεις είναι εξαιρετικά σπάνιες).
Με άλλα λόγια, οι 63 διεργασίες που τρέχουν στο σύστημα μου χρησιμοποιούν απο κοινού την libc. Συμπεριλαμβανομένου και του Firefox.
Όταν το ps (και τα παρόμοια προγράμματα) αναφέρουν πόση μνήμη χρησιμοποιεί ένα πρόγραμμα, δεν λαμβάνουν υπ'όψην το γεγονός οτι μια shared βιβλιοθήκη μπορεί να χρησιμοποιηθεί απο πολλαπλά προγράμματα. Αντίθετα οι αριθμοί που παρουσιάζουν είναι εσφαλμένοι απο την άποψη οτι για κάθε χρήση μιας βιβλιοθήκης, ο αριθμός που παρουσιάζεται αναφέρεται σε ολόκληρη την βιβλιοθήκη. Δηλαδή αν δύο προγράμματα χρησιμοποιούν την ίδια βιβλιοθήκη, τότε η μνήμη που καταλαμβάνει ο κώδικας μηχανής της βιβλιοθήκης αυτής θα μετρηθεί δύο φορές.
Αν και αυτό φαίνεται λανθασμένο αρχικά, στην πραγματικότητα δεν είναι. Τα προγράμματα αυτά αναφέρονται στο ποσό της μνήμης που χρησιμοποιεί το εκάστοτε πρόγραμμα, ανεξάρτητα αν αυτή η μνήμη χρησιμοποιείται αποκλειστικά απο το πρόγραμμα αυτό ή όχι.
Όμως αν θελήσουμε να μετρήσουμε πόση πραγματικα μνήμη χρησιμοποιεί ένα πρόγραμμα, η διαδιασία είναι δύσκολη. Για την ακρίβεια, δημιουργείται το εύλογο ερώτημα "τι θεωρούμε ως μνήμη που χρησιμοποιεί το πρόγραμμα;".
Η απάντηση είναι δύσκολη γιατί απο την στιγμή που ένα πρόγραμμα χρησιμοποιεί μια βιβλιοθήκη μαζί με άλλα 9 προγράμματα, πως θα υπολογίσουμε το πόση μνήμη καταναλώνει αυτή η βιβλιοθήκη όσο αφορά το πρόγραμμα; Ανάλογα με την περίπτωση, θα μπορούσαμε να αγνοήσουμε την βιβλιοθήκη αυτή (κάτι που θα ήταν πιθανότατα λογικό όσο αφορά βασικές βιβλιοθήκες όπως η libc) ή να την συμπεριλάβουμε. Επίσης θα μπορούσαμε να διαιρέσουμε την μνήμη που καταλαμβάνει η βιβλιοθήκη με τις διεργασίες που την χρησιμοποιούν. Αυτό το τελευταίο θα ήταν η καλύτερη λύση, αν δεν υπήρχε ένα μικρό πρόβλημα: ένα πρόγραμμα μπορεί να χρησιμοποιεί μόνο το 1% απο τις λειτουργίες μιας βιβλιοθήκης και τo Linux δεν θα κατανέμει περισσότερη μνήμη απ'όσο χρειάζεται. Με άλλα λόγια αν ένα πρόγραμμα χρησιμοποιεί 2 απο τις 200 λειτουργίες μιας βιβλιοθήκης, το Linux θα φορτώσει γι'αυτό το πρόγραμμα μόνο τις 2 λειτουργίες. Αν όλα τα προγράμματα χρησιμοποιούν μόνο 149 απο τις 200, τότε στην μνήμη θα υπάρχουν οι 149 λειτουργίες. Αλλά κάθε πρόγραμμα μπορεί να χρησιμοποιεί διαφορετικό αριθμό λειτουργιών και οι λειτουργίες αυτές εσωτερικά να αναφέρονται σε άλλες.
Απο την στιγμή που τέτοιες επιλογές δεν είναι ξεκάθαρες, οι υπολογισμοί μπορούν να γίνουν μόνο ανα περίπτωση. Αλλά και με αυτή την χρήση, τα αποτελέσματα πάλι δεν θα είναι ακριβή.
Για να γυρίσουμε πίσω στο Firefox. Το Firefox χρησιμοποιεί μια πλειάδα βιβλιοθηκών, συμπεριλαμβανομένων της GTK+ 2.x, GLib, Pango, libpng, libjpeg, libX11, κ.α. Ειδικά η GTK+ και η libX11 και κάπως λιγότερο η GLib είναι βιβλιοθήκες σεβαστών κυβικών. Αλλά παρομοίως είναι και βιβλιοθήκες που χρησιμοποιούνται πολύ συχνά. Για παράδειγμα, η GTK+ και η GLib χρησιμοποιούνται απο την πλειοψηφία των προγραμμάτων που θα συναντήσουμε σε ένα τυπικό GNOME-based σύστημα ενώ η βιβλιοθήκη libX11 χρησιμοποιείται απο όλα τα προγράμματα που τρέχουν κάτω από τα X Windows (δηλαδή οτιδήποτε βλέπουμε σε παραθυρικό γραφικό περιβάλλον).
Με άλλα λόγια, ένα μέρος των 60mb που ανέφερα παραπάνω χρησιμοποιείται και απο άλλα προγράμματα. Ένα χρήσιμο προγραμματάκι για να βρούμε τι ακριβώς αντιστοιχεί που, είναι το "pmap", το οποίο το χρησιμοποιούμε ως εξής:
HTML:
pmap -x pid
Το pid είναι το process id του προγράμματος. Για να βρούμε το process id ενός προγράμματος γράφουμε:
HTML:
ps -A | grep εκτελέσιμο
Όπου εκτελέσιμο είναι το εκτελέσιμο πρόγραμμα (ή μέρος του εκτελέσιμου προγράμματος) του προγράμματος του οποίου θέλουμε να δούμε την χαρτογράφηση της μνήμης. Στην περίπτωση του Firefox απλά γράφουμε firefox (το εκτελέσιμο είναι firefox-bin αλλά επειδή το firefox είναι μέρος του firefox-bin θα βγάλει σωστά αποτελέσματα). Πιθανότατα αυτή η εντολή να βγάλει πολλά αποτελέσματα (κάτι το σίγουρο στην περίπτωση του Firefox). Το εκτελέσιμο που ζητάμε συνήθως είναι αυτό με την μεγαλύτερη κατανάλωση μνήμης ή αυτό που έχει "bin", "unix", "linux" ή γενικότερα κάποιο αναγνωριστικό σαν μέρος του ονόματος του.
Απο την γραμμή του προγράμματος που βρίσκουμε, το pid είναι ο δεύτερος αριθμός.
Όταν εκτελέσουμε την pmap βλέπουμε διάφορα κομμάτια μνήμης. Στην έκτη στήλη κάθε κομματιού (αυτή με την επικεφαλίδα Mode) φαίνεται τι είδος δεδομένων περιέχει το κομμάτι. Αν περιέχει εκτελέσιμο κώδικα, ο τρίτος χαρακτήρας του mode θα είναι "x" (συνήθως με τον πρώτο να είναι "r" και με συνηθέστερη χρήση την "r-x--"). Αν περιέχει δεδομένα, ο τρίτος χαρακτήρας θα είναι "-" και ο πρώτος και ο δεύτερος χαρακτήρας συνήθως θα είναι "r" και "w" αντίστοιχα, που δηλώνει αν τα δεδομένα μπορούν να διαβαστούν ("r" - read) ή/και να γραφτούν ("w" - write).
Συνήθως τα shared κομμάτια μνήμης που χρησιμοποιούνται απο περισσότερες απο μια διεργασίες είναι μόνο για ανάγνωση - δηλαδή δεν έχουν τον δεύτερο χαρακτήρα σαν "w" αλλά σαν "-".
Ένα παράδειγμα στην περίπτωση του Firefox είναι τα αρκετά fonts τα οποία είναι shared μεταξύ άλλων εφαρμογών. Αν αυτά τα fonts χρησιμοποιούνται και απο άλλες εφαρμογές, θα υπάρχουν στην μνήμη είτε είναι ανοικτός (φορτωμένος) ο Firefox είτε όχι. Για παράδειγμα το default font του GNOME, απο την στιγμή που τρέχει τo GNOME δεν θα έχει καμία επίπτωση στην μνήμη ακόμα και αν χρησιμοποείται απο το Firefox και βρίσκεται στην λίστα που παράγει το pmap.
Αν διαβάσετε την λίστα που βγάζει το pmap για το Firefox θα δείτε οτι μέσα στις πολλά κομμάτια μνήμης, υπάρχουν και τρία για την libc:
HTML:
b74e2000 1160 - ;- - r-x-- libc-2.5.so
b7604000 8 &nb sp; - &n bsp; - - r---- libc-2.5.so
b7606000 4 &nb sp; - &n bsp; - - rw--- libc-2.5.so
Η πρώτη στήλη μπορεί να αγνοηθεί γιατί είναι απλά η θέση στην μνήμη που βρίσκεται το κομμάτι. Η δεύτερη στήλη αναφέρεται στο μέγεθος του κομματιού. Σε αυτή την περίπτωση μπορούμε να δούμε οτι το Firefox στο πρώτο κομμάτι χρησιμοποιεί περίπου 1mb από την libc (η libc είναι αρκετά μεγαλύτερη - σε εμένα πχ είναι 6.7mb - αλλά το Firefox δεν χρησιμοποιεί όλες τις λειτουργίες της). Όπως αναφέρθηκε παραπάνω, αυτά τα 1mb δεν είναι αποκλειστικά στο Firefox. Αντίθετα είναι κοινή μνήμη που χρησιμοποιείται και απο άλλες διεργασίες,. Η τρίτη, τέταρτη και πέμπτη στήλη δεν μας ενδιαφέρει και στην έκτη στήλη βλέπουμε το mode του κάθε κομματιού.
Απο τα παραπάνω τρία κομμάτια βλέπουμε οτι το πρώτο κομμάτι είναι εκτελέσιμος κώδικας - άρα shared κώδικας αφού η libc-2.5.so.6 είναι shared object - το δεύτερο κομμάτι είναι δεδομένα μόνο άνάγνωσης, άρα κοινά δεδομένα μεταξύ όλων των διεργασιών που χρησιμοποιούν την libc και τέλος το τρίτο κομμάτι είναι δεδομένα εγγραφής και ανάγνωσης, άρα τοπικά δεδομένα τα οποία είναι αποκλειστικά για το Firefox.
Χρησιμοποιώντας αυτό το εργαλείο, μπορούμε να βγάλουμε μια γενική εικόνα για το πόση μνήμη καταναλώνει ένα πρόγραμμα αν και λόγω της κοινής χρήσης της μνήμης μια ακριβή εικόνα είναι αρκετά δύσκολο να δημιουργηθεί.
Όμως αυτό που έχει σημασία, καθώς και λόγος που έκανα όλη αυτή την ανάλυση, είναι να γίνει κατανοητό οτι στο Linux η διαχείρηση της μνήμης είναι μια περίπλοκη υπόθεση και εκ πρώτης όψεως αν κάποιος δεν γνωρίζει πως χρησιμοποιείται η μνήμη απο τον πυρήνα μπορεί να βγάλει λανθασμένα συμπεράσματα χρησιμοποιώντας προγράμματα όπως το 'ps' και το 'system monitor'.
Στην τελική, όπως γράφει και το topic του post, το σύστημα "δεν τρώει τόση μνήμη όση φαίνεται". Η κατανάλωση μνήμης είναι ένα illusion που υπάρχει σε αρκετούς χρήστες, νέους και παλιούς, του λειτουργικού λόγω του τρόπου με τον οποίο παρουσιάζεται απο το 'ps' και τα παρόμοια προγράμματα καθώς και απο την έλλειψη γνώσης σχετικά με το πως διαχειρίζεται την μνήμη το λειτουργικό.
Όπως φαίνεται, το Linux κάνει πάρα πολύ καλή διαχείρηση της μνήμης, ενώ ο τρόπος με τον οποίο αυτή γίνεται δείχνει οτι αν χρησιμοποιούμε προγράμματα τα οποία χρησιμοποιούν τις ίδιες βιβλιοθήκες (πχ GTK+ 2.x προγράμματα) θα έχουμε καλύτερα αποτελέσματα απο το αν χρησιμοποιούμε προγράμματα που χρησιμοποιούν διαφορετικές βιβλιοθήκες (πχ GTK+ 2.x προγράμματα, Qt προγράμματα, Fltk προγράμματα, κλπ).
Αν και μακροσκελές αξίζει να του ρίξετε μια ματιά.
Έχει τίτλο: Μνήμη στο Linux (ή "όχι,δεν τρώει τόση")
Αν ανοίξετε κάποιο memory monitor, το πρόγραμμα top ή δώσετε την εντολή free στην κονσόλα, πιθανότατα να δείτε μετά απο λίγα λεπτά χρήσης του υπολογιστή οτι η ελεύθερη μνήμη έχει κατέβει σε πολύ χαμηλά επίπεδα, ακόμα και αν έχετε 1gb μνήμης. Αν δείτε κάποια απο τα προγράμματα να τρέχουν, θα προσέξετε σε κάποιες στήλες να αναγράφονται ποσά του στυλ "600mb μνήμης" εδώ, και "500mb μνήμης" εκεί, κλπ.
Λογικό είναι να ταραχτείτε με την απορία: "μα πόση μνήμη θέλει τέλος πάντων;".
Ηρεμία. Δεν είναι τα πράγματα όπως φαίνονται.
Το Linux είναι ένα σύστημα φτιαγμένο απο πολλά μικρά αρχεία και πολλές βιβλιοθήκες οι οποίες βρίσκονται σε μορφή .so (shared object - κάτι σαν τα DLL των Windows). Επίσης οι ρυθμίσεις των διαφόρων προγραμμάτων βρίσκονται σε αρχεία κειμένου. Σχεδόν για κάθε πρόγραμμα που υπάρχει στο σύστημα (και μιλάμε για αρκετά προγράμματα - γράφοντας ls /{,usr/}{bin,sbin} | wc -l στην κονσόλα θα σας βγάλει τον αριθμό των περισσοτέρων προγραμμάτων που υπάρχουν εγκατεστημένα) υπάρχει κάπου και κάποιο configuration file (συνήθως στο /etc). Σε αυτά τα αρχεία, τα οποία πρέπει να εκτελούνται αρκετά συχνά αφού αρκετά κάνουν συγκεκριμένη δουλειά (πχ αν ανοίγετε ένα φάκελο απο το Nautilus του GNOME, το πρόγραμμα "file" εκτελείται για κάθε αρχείο ώστε να γνωρίζει ο Nautilus τι είδους αρχείο είναι αυτό, ενώ αν αποσυμπιέζετε ένα αρχείο .tar.gz, το GNOME file-roller καλεί το "tar" για να εξάγει τα αρχεία απο το archive, το οποίο με την σειρά του καλεί το gzip για να αποσυμπιέσει το archive, klp) προσθέστε και την περίπτωση το μηχάνημα να τρέχει σαν web ή database server όπου πολλά -συνήθως μικρά- αρχεία θα πρέπει να διαβάζονται συχνά και καταλήγετε στο συμπέρασμα οτι το Linux όλη την ώρα καλεί και διαβάζει απο τον δίσκο μικρά αρχεία.
Για να έχει καλύτερη απόδοση κάνοντας αυτές τις δουλειές, ο πυρήνας του Linux χρησιμοποιεί την αδέσμευτη μνήμη (την μνήμη που γενικότερα δεν χρησιμοποιείται απο τα προγράμματα) ώστε να σώσει δεδομένα που διαβάστηκαν πρόσφατα αρκετά συχνά απο τον δίσκο, ώστε την επόμενη φορά που θα ζητηθούν να βρίσκονται ήδη στην μνήμη, γλυτώνοντας το disk access το οποίο αφ'ενός θα ήταν πολύ πιο αργό και αφ'ετέρου θα μείωνε την ζωή του σκληρού δίσκου.
Αυτή η μνήμη είναι η λεγόμενη "cached μνήμη" του συστήματος.
Συχνά διάφορα προγράμματα εκτελούν άλλα με τα οποία χρειάζεται να επικοινωνούν (για παράδειγμα το "tar" εκτελεί το "gzip" για να αποσυμπιέσει ένα αρχείο .tar.gz). Επίσης συχνά κάποια προγράμματα έχουν διάφορα αρχεία ανοικτά για ένα χρονικό διάστημα (πχ όταν κάποιο αρχείο κατεβαίνει απο το Internet, το αρχείο στο οποίο σώζεται μένει ανοικτό για όλο το διάστημα του "κατεβάσματος").
Για την επικοινωνία μεταξύ των προγραμμάτων και γι'αυτά τα αρχεία (καθώς και για άλλα special αρχεία), ο πυρήνας δεσμεύει μνήμη ώστε να αποθηκεύει διάφορες πληροφορίες και τα κομμάτια των αρχείων που επεξεργάζεται. Αυτές η πληροφορίες σώζονται στους "buffers".
Έτσι πέρα απο την μνήμη που καταναλώνουν τα προγράμματα για τον εαυτό τους, υπάρχει και η cached μνήμη καθώς και η μνήμη που χρησιμοποιείται για τους buffers.
Αν ανοίξετε μια κονσόλα και γράψετε free -m θα δείτε τα διάφορα ποσά μνήμης σε megabytes (αν δεν δώσετε την παράμετρο -m θα δείτε τα ποσά σε kilobytes). Για παράδειγμα εγώ που έχω 512mb μνήμης, έχω τα παρακάτω αποτελέσματα:
Απο τα παραπάνω φαίνεται σαν η χρησιμοποιημένη μνήμη να είναι 189mb και η ελεύθερη να είναι 312mb (σημείωση: η συνολική μνήμη αναφέρεται σαν 502mb αντί για 512mb γιατί τα 10mb τα χρησιμοποιεί ο πυρήνας για τα δικά του δεδομένα).
Όμως όπως ανέφερα παραπάνω, η cached μνήμη που χρησιμοποιεί ο πυρήνας είναι ουσιαστικά αδέσμευτη μνήμη την οποία το σύστημα "δανείζεται". Αυτή η μνήμη απελευθερώνεται απο το σύστημα αν κάποιο πρόγραμμα την ζητήσει (δηλαδή δεν είναι "δεσμευμένη" απο κάποιο άλλο). Επίσης υπάρχουν και οι buffers οι οποίοι χρησιμοποιούνται για την μεταφορά δεδομένων μεταξύ προγραμμάτων ή για την χρήση διαφόρων αρχείων. Η μνήμη των buffers, όπως και η cached μνήμη, δεν είναι δεσμευμένη αλλά χρησιμοποιείται προσωρινά.
Έτσι ουσιαστικά η διαθέσιμη μνήμη του συστήματος περιλαμβάνει την ελεύθερη μνήμη, την cached μνήμη και την μνήμη που έχει κατανεμηθεί για τους buffers.
Με άλλα λόγια, η μνήμη που το σύστημα μου έχει διαθέσιμη είναι 416mb ενώ μόνο 85mb χρησιμοποιούνται απο τα προγράμματα. Αυτό φαίνεται με μια ματιά απο την μεσαία γραμμή:
HTML:
-/+ buffers/cache: 85 416
Ο πυρήνας του Linux προσπαθεί συνεχώς να χρησιμοποιεί το μεγαλύτερο μέρος της αδέσμευτης μνήμης για cache ώστε να επιτυγχάνεται μεγαλύτερη ταχύτητα στην προσπέλαση δεδομένων στον δίσκο. Αυτό το επιτυγχάνει τοποθετόντας τα δεδομένα των αρχείων που φορτώνονται ή γράφονται στην αδέσμευτη μνήμη μέχρι αυτά να διαγραφούν ή η cache να γεμίσει και να αντικατασταθούν με νεότερα δεδομένα ή κάποιο πρόγραμμα να χρειαστεί περισσότερη απο την ελεύθερη μνήμη.
Έτσι αν ανοίξετε κάποιο πρόγραμμα και χρησιμοποιήσετε δεδομένα 300mb μέσω του προγράμματος, τα δεδομένα αυτά δεν θα φύγουν απο την cached μνήμη όταν κλείσετε το πρόγραμμα (εκτός φυσικά κι αν γεμίσει η cache ή η μνήμη ζητηθεί απο κάποιο πρόγραμμα, όπως ανέφερα παραπάνω). Αυτό γίνεται γιατί μπορεί αυτά τα δεδομένα να ξαναχρησιμοποιηθούν σύντομα. Ο πυρήνας φροντίζει να χρησιμοποιήσει το μεγαλύτερο μέρος της αδέσμευτης μνήμης ως cache καθώς χρησιμοποιείτε αρχεία, αλλά πάντα αφήνει ένα σχετικά μικρό μέρος της μνήμης ελεύθερο. Ο λόγος γι'αυτό είναι οτι είναι γρηγορότερη η δέσμευση μνήμης απο την ελεύθερη περιοχή της μνήμης παρά απο την cached.
Ένα άλλο θέμα που ανέφερα στην αρχή είναι τα προγράμματα που καταβροχθίζουν μνήμη σε ρυθμούς μεγαλύτερους απο οτι οι ακρίδες καταβροχθίζουν τις φυτείες. Αλλά όπως και παραπάνω, το πρόβλημα είναι ουσιαστικά πλασματικό.
Όπως ανέφερα, το Linux αποτελείται απο πολλά προγράμματα και -το κυριότερο- βιβλιοθήκες σε μορφή shared objects. Επίσης, απο σχεδιασμού του λειτουργικού συστήματος, η πρόσβαση σε διάφορες συσκευές γίνεται μέσω της χρήσης ειδικών αρχείων τα οποία βρίσκονται στον κατάλογο /dev.
Όταν ένα πρόγραμμα τρέχει, χρησιμοποιεί κάποιες απο αυτές τις shared βιβλιοθήκες (με την κυριότερη να είναι η libc - ή αλλιώς c library - η οποία συνήθως βρίσκεται στο αρχείο /libc/libc.so.6) ενώ συχνά χρησιμοποιεί και κάποιες συσκευές (πχ κάρτα ήχου) μέσω των ειδικών τους αρχείων.
Η μνήμη που χρησιμοποιεί (επεξεργάζεται ή εκτελεί εντολές σε αυτήν μέσω της CPU) ένα πρόγραμμα χωρίζεται στις εξής κατηγορίες:
1. Την μνήμη που καταλαμβάνει ο κώδικας μηχανής του ίδιου του προγράμματος.
2. Την μνήμη που καταλαμβάνει ο κώδικας μηχανής των βιβλιοθηκών που χρησιμοποιεί το πρόγραμμα.
3. Την μνήμη που καταλαμβάνουν τα δεδομένα που επεξεργάζεται το πρόγραμμα.
4. Την μνήμη που καταλαμβάνουν τα δεδομένα που επεξεργάζονται οι βιβλιοθήκες που χρησιμοποιεί το πρόγραμμα και είναι αποκλειστικά για το πρόγραμμα.
5. Την μνήμη που καταλαμβάνουν τα δεδομένα που επεξεργάζονται οι βιβλιοθήκες που χρησιμοποιεί το πρόγραμμα και είναι κοινή για όλα τα προγράμματα που τις χρησιμοποιούν.
Εκτελώντας "ps aux" στην κονσόλα ώστε να δούμε πληροφορίες για την μνήμη που χρησιμοποιούν οι διάφορες διεργασίες (προγράμματα) που τρέχουν, βλέπουμε την εξής γραμμή για το Firefox (δεδομένου οτι το έχουμε ανοικτό :-Ρ):
HTML:
1000 2676 0.9 11.9 154636 61408 tty3 Sl 06:12& nbsp; 1:30 /usr/local/lib/firefox-2.0.0.3/firefox-bin
Το ενδιαφέρον είναι οι τιμές 154636 (έχει την επικεφαλίδα VSZ) και 61408 (έχει την επικεφαλίδα RSS). Αυτές δείχνουν την συνολική (154636kb) και εν χρήση (61408kb) μνήμη. Η διαφορά της συνολικής (virtual size) και εν χρήση (resident) είναι οτι η συνολική αναφέρεται γενικότερα στην μνήμη που χρησιμοποιεί το πρόγραμμα, συμπεριλαμβανομένων ανοικτών ή memory mapped αρχείων, συσκευών (πχ μνήμη στην κάρτα γραφικών), κ.α. ενώ η εν χρήση αναφέρεται στην φυσική μνήμη την οποία επεξεργάζεται το πρόγραμμα ή οι βιβλιοθήκες που χρησιμοποιεί.
Πριν όμως σκεφτείτε οτι το Firefox τρώει 150mb (ή 60mb) μνήμης σκεφτείτε πως, όπως αναφέρθηκε παραπάνω απο την free, όλο το σύστημα τρώει γύρω στα 85mb μνήμης. Και φυσικά δεν έχω ανοικτό μόνο το Firefox. Για την ακρίβεια, γράφοντας ps -A | wc -l για να μετρήσω τον αριθμό των processes, βλέπω οτι τρέχουν 63 processes (αυτό δεν σημαίνει οτι τρέχουν 63 προγράμματα, αλλά γενικότερα ο αριθμός των προγραμμάτων είναι σχετικά μεγάλος).
Πως είναι δυνατό αυτό όμως;
Είναι απλό. Η μνήμη στην οποία αναφέρεται το ps (όπως και τα περισσότερα προγράμματα τα οποία αναφέρουν την χρήση μνήμης - πχ το system monitor του GNOME), είναι η μνήμη την οποία χρησιμοποιεί το πρόγραμμα - αλλά όχι απαραίτητα μνήμη η οποία χρησιμοποιείται μόνο απο το πρόγραμμα!
Όπως ανέφερα παραπάνω, τα προγράμματα στο Linux χρησιμοποιούν πολλές βιβλιοθήκες σε μορφή shared objects. Αν δύο προγράμματα χρησιμοποιήσουν την ίδια βιβλιοθήκη, τότε ο κώδικας μηχανής της βιβλιοθήκης θα φορτωθεί στην μνήμη μόνο μια φορά. Το ίδιο ισχύει και για τις βιβλιοθήκες που χρησιμοποιούνται απο άλλες βιβλιοθήκες. Στην τελική, κάθε βιβλιοθήκη σε shared object μορφή, θα χρησιμοποιηθεί μόνο μια φορά.
Η σημαντικότερη βιβλιοθήκη του συστήματος είναι η libc. Αυτή προσφέρει τις βασικές λειτουργίες του συστήματος, όπως την διαχείρηση των αρχείων και της μνήμης. Αυτή η βιβλιοθήκη βρίσκεται στο /lib/libc.so.6 (ή .5 για παλιότερα συστήματα) και είναι -όπως δηλώνει η επέκταση της- ένα shared object, με αποτέλεσμα να φορτώνεται μόνο μια φορά και να χρησιμοποιείται απο όλα τα προγράμματα (με ελάχιστες εξαιρέσεις προγραμμάτων που κάνουν απευθείας κλήσεις στον πυρήνα ή έχουν την βιβλιοθήκη statically linked σε αυτά - αλλά αυτές οι περιπτώσεις είναι εξαιρετικά σπάνιες).
Με άλλα λόγια, οι 63 διεργασίες που τρέχουν στο σύστημα μου χρησιμοποιούν απο κοινού την libc. Συμπεριλαμβανομένου και του Firefox.
Όταν το ps (και τα παρόμοια προγράμματα) αναφέρουν πόση μνήμη χρησιμοποιεί ένα πρόγραμμα, δεν λαμβάνουν υπ'όψην το γεγονός οτι μια shared βιβλιοθήκη μπορεί να χρησιμοποιηθεί απο πολλαπλά προγράμματα. Αντίθετα οι αριθμοί που παρουσιάζουν είναι εσφαλμένοι απο την άποψη οτι για κάθε χρήση μιας βιβλιοθήκης, ο αριθμός που παρουσιάζεται αναφέρεται σε ολόκληρη την βιβλιοθήκη. Δηλαδή αν δύο προγράμματα χρησιμοποιούν την ίδια βιβλιοθήκη, τότε η μνήμη που καταλαμβάνει ο κώδικας μηχανής της βιβλιοθήκης αυτής θα μετρηθεί δύο φορές.
Αν και αυτό φαίνεται λανθασμένο αρχικά, στην πραγματικότητα δεν είναι. Τα προγράμματα αυτά αναφέρονται στο ποσό της μνήμης που χρησιμοποιεί το εκάστοτε πρόγραμμα, ανεξάρτητα αν αυτή η μνήμη χρησιμοποιείται αποκλειστικά απο το πρόγραμμα αυτό ή όχι.
Όμως αν θελήσουμε να μετρήσουμε πόση πραγματικα μνήμη χρησιμοποιεί ένα πρόγραμμα, η διαδιασία είναι δύσκολη. Για την ακρίβεια, δημιουργείται το εύλογο ερώτημα "τι θεωρούμε ως μνήμη που χρησιμοποιεί το πρόγραμμα;".
Η απάντηση είναι δύσκολη γιατί απο την στιγμή που ένα πρόγραμμα χρησιμοποιεί μια βιβλιοθήκη μαζί με άλλα 9 προγράμματα, πως θα υπολογίσουμε το πόση μνήμη καταναλώνει αυτή η βιβλιοθήκη όσο αφορά το πρόγραμμα; Ανάλογα με την περίπτωση, θα μπορούσαμε να αγνοήσουμε την βιβλιοθήκη αυτή (κάτι που θα ήταν πιθανότατα λογικό όσο αφορά βασικές βιβλιοθήκες όπως η libc) ή να την συμπεριλάβουμε. Επίσης θα μπορούσαμε να διαιρέσουμε την μνήμη που καταλαμβάνει η βιβλιοθήκη με τις διεργασίες που την χρησιμοποιούν. Αυτό το τελευταίο θα ήταν η καλύτερη λύση, αν δεν υπήρχε ένα μικρό πρόβλημα: ένα πρόγραμμα μπορεί να χρησιμοποιεί μόνο το 1% απο τις λειτουργίες μιας βιβλιοθήκης και τo Linux δεν θα κατανέμει περισσότερη μνήμη απ'όσο χρειάζεται. Με άλλα λόγια αν ένα πρόγραμμα χρησιμοποιεί 2 απο τις 200 λειτουργίες μιας βιβλιοθήκης, το Linux θα φορτώσει γι'αυτό το πρόγραμμα μόνο τις 2 λειτουργίες. Αν όλα τα προγράμματα χρησιμοποιούν μόνο 149 απο τις 200, τότε στην μνήμη θα υπάρχουν οι 149 λειτουργίες. Αλλά κάθε πρόγραμμα μπορεί να χρησιμοποιεί διαφορετικό αριθμό λειτουργιών και οι λειτουργίες αυτές εσωτερικά να αναφέρονται σε άλλες.
Απο την στιγμή που τέτοιες επιλογές δεν είναι ξεκάθαρες, οι υπολογισμοί μπορούν να γίνουν μόνο ανα περίπτωση. Αλλά και με αυτή την χρήση, τα αποτελέσματα πάλι δεν θα είναι ακριβή.
Για να γυρίσουμε πίσω στο Firefox. Το Firefox χρησιμοποιεί μια πλειάδα βιβλιοθηκών, συμπεριλαμβανομένων της GTK+ 2.x, GLib, Pango, libpng, libjpeg, libX11, κ.α. Ειδικά η GTK+ και η libX11 και κάπως λιγότερο η GLib είναι βιβλιοθήκες σεβαστών κυβικών. Αλλά παρομοίως είναι και βιβλιοθήκες που χρησιμοποιούνται πολύ συχνά. Για παράδειγμα, η GTK+ και η GLib χρησιμοποιούνται απο την πλειοψηφία των προγραμμάτων που θα συναντήσουμε σε ένα τυπικό GNOME-based σύστημα ενώ η βιβλιοθήκη libX11 χρησιμοποιείται απο όλα τα προγράμματα που τρέχουν κάτω από τα X Windows (δηλαδή οτιδήποτε βλέπουμε σε παραθυρικό γραφικό περιβάλλον).
Με άλλα λόγια, ένα μέρος των 60mb που ανέφερα παραπάνω χρησιμοποιείται και απο άλλα προγράμματα. Ένα χρήσιμο προγραμματάκι για να βρούμε τι ακριβώς αντιστοιχεί που, είναι το "pmap", το οποίο το χρησιμοποιούμε ως εξής:
HTML:
pmap -x pid
Το pid είναι το process id του προγράμματος. Για να βρούμε το process id ενός προγράμματος γράφουμε:
HTML:
ps -A | grep εκτελέσιμο
Όπου εκτελέσιμο είναι το εκτελέσιμο πρόγραμμα (ή μέρος του εκτελέσιμου προγράμματος) του προγράμματος του οποίου θέλουμε να δούμε την χαρτογράφηση της μνήμης. Στην περίπτωση του Firefox απλά γράφουμε firefox (το εκτελέσιμο είναι firefox-bin αλλά επειδή το firefox είναι μέρος του firefox-bin θα βγάλει σωστά αποτελέσματα). Πιθανότατα αυτή η εντολή να βγάλει πολλά αποτελέσματα (κάτι το σίγουρο στην περίπτωση του Firefox). Το εκτελέσιμο που ζητάμε συνήθως είναι αυτό με την μεγαλύτερη κατανάλωση μνήμης ή αυτό που έχει "bin", "unix", "linux" ή γενικότερα κάποιο αναγνωριστικό σαν μέρος του ονόματος του.
Απο την γραμμή του προγράμματος που βρίσκουμε, το pid είναι ο δεύτερος αριθμός.
Όταν εκτελέσουμε την pmap βλέπουμε διάφορα κομμάτια μνήμης. Στην έκτη στήλη κάθε κομματιού (αυτή με την επικεφαλίδα Mode) φαίνεται τι είδος δεδομένων περιέχει το κομμάτι. Αν περιέχει εκτελέσιμο κώδικα, ο τρίτος χαρακτήρας του mode θα είναι "x" (συνήθως με τον πρώτο να είναι "r" και με συνηθέστερη χρήση την "r-x--"). Αν περιέχει δεδομένα, ο τρίτος χαρακτήρας θα είναι "-" και ο πρώτος και ο δεύτερος χαρακτήρας συνήθως θα είναι "r" και "w" αντίστοιχα, που δηλώνει αν τα δεδομένα μπορούν να διαβαστούν ("r" - read) ή/και να γραφτούν ("w" - write).
Συνήθως τα shared κομμάτια μνήμης που χρησιμοποιούνται απο περισσότερες απο μια διεργασίες είναι μόνο για ανάγνωση - δηλαδή δεν έχουν τον δεύτερο χαρακτήρα σαν "w" αλλά σαν "-".
Ένα παράδειγμα στην περίπτωση του Firefox είναι τα αρκετά fonts τα οποία είναι shared μεταξύ άλλων εφαρμογών. Αν αυτά τα fonts χρησιμοποιούνται και απο άλλες εφαρμογές, θα υπάρχουν στην μνήμη είτε είναι ανοικτός (φορτωμένος) ο Firefox είτε όχι. Για παράδειγμα το default font του GNOME, απο την στιγμή που τρέχει τo GNOME δεν θα έχει καμία επίπτωση στην μνήμη ακόμα και αν χρησιμοποείται απο το Firefox και βρίσκεται στην λίστα που παράγει το pmap.
Αν διαβάσετε την λίστα που βγάζει το pmap για το Firefox θα δείτε οτι μέσα στις πολλά κομμάτια μνήμης, υπάρχουν και τρία για την libc:
HTML:
b74e2000 1160 - ;- - r-x-- libc-2.5.so
b7604000 8 &nb sp; - &n bsp; - - r---- libc-2.5.so
b7606000 4 &nb sp; - &n bsp; - - rw--- libc-2.5.so
Η πρώτη στήλη μπορεί να αγνοηθεί γιατί είναι απλά η θέση στην μνήμη που βρίσκεται το κομμάτι. Η δεύτερη στήλη αναφέρεται στο μέγεθος του κομματιού. Σε αυτή την περίπτωση μπορούμε να δούμε οτι το Firefox στο πρώτο κομμάτι χρησιμοποιεί περίπου 1mb από την libc (η libc είναι αρκετά μεγαλύτερη - σε εμένα πχ είναι 6.7mb - αλλά το Firefox δεν χρησιμοποιεί όλες τις λειτουργίες της). Όπως αναφέρθηκε παραπάνω, αυτά τα 1mb δεν είναι αποκλειστικά στο Firefox. Αντίθετα είναι κοινή μνήμη που χρησιμοποιείται και απο άλλες διεργασίες,. Η τρίτη, τέταρτη και πέμπτη στήλη δεν μας ενδιαφέρει και στην έκτη στήλη βλέπουμε το mode του κάθε κομματιού.
Απο τα παραπάνω τρία κομμάτια βλέπουμε οτι το πρώτο κομμάτι είναι εκτελέσιμος κώδικας - άρα shared κώδικας αφού η libc-2.5.so.6 είναι shared object - το δεύτερο κομμάτι είναι δεδομένα μόνο άνάγνωσης, άρα κοινά δεδομένα μεταξύ όλων των διεργασιών που χρησιμοποιούν την libc και τέλος το τρίτο κομμάτι είναι δεδομένα εγγραφής και ανάγνωσης, άρα τοπικά δεδομένα τα οποία είναι αποκλειστικά για το Firefox.
Χρησιμοποιώντας αυτό το εργαλείο, μπορούμε να βγάλουμε μια γενική εικόνα για το πόση μνήμη καταναλώνει ένα πρόγραμμα αν και λόγω της κοινής χρήσης της μνήμης μια ακριβή εικόνα είναι αρκετά δύσκολο να δημιουργηθεί.
Όμως αυτό που έχει σημασία, καθώς και λόγος που έκανα όλη αυτή την ανάλυση, είναι να γίνει κατανοητό οτι στο Linux η διαχείρηση της μνήμης είναι μια περίπλοκη υπόθεση και εκ πρώτης όψεως αν κάποιος δεν γνωρίζει πως χρησιμοποιείται η μνήμη απο τον πυρήνα μπορεί να βγάλει λανθασμένα συμπεράσματα χρησιμοποιώντας προγράμματα όπως το 'ps' και το 'system monitor'.
Στην τελική, όπως γράφει και το topic του post, το σύστημα "δεν τρώει τόση μνήμη όση φαίνεται". Η κατανάλωση μνήμης είναι ένα illusion που υπάρχει σε αρκετούς χρήστες, νέους και παλιούς, του λειτουργικού λόγω του τρόπου με τον οποίο παρουσιάζεται απο το 'ps' και τα παρόμοια προγράμματα καθώς και απο την έλλειψη γνώσης σχετικά με το πως διαχειρίζεται την μνήμη το λειτουργικό.
Όπως φαίνεται, το Linux κάνει πάρα πολύ καλή διαχείρηση της μνήμης, ενώ ο τρόπος με τον οποίο αυτή γίνεται δείχνει οτι αν χρησιμοποιούμε προγράμματα τα οποία χρησιμοποιούν τις ίδιες βιβλιοθήκες (πχ GTK+ 2.x προγράμματα) θα έχουμε καλύτερα αποτελέσματα απο το αν χρησιμοποιούμε προγράμματα που χρησιμοποιούν διαφορετικές βιβλιοθήκες (πχ GTK+ 2.x προγράμματα, Qt προγράμματα, Fltk προγράμματα, κλπ).