nickname2016 Δημοσ. 22 Μαρτίου 2016 Δημοσ. 22 Μαρτίου 2016 Πολλες αποριες, πολυ ψαξιμο. Απο αυτα που καταλαβα, η στοιβα(stack) ειναι ενας χωρος μνημης που αποθηκευονται αυτοματα, τοπικες μεταβλητες και πληροφοριες που αφορουν κλησεις συναρτησεων, διευθυνσης επιστροφης κλπ. πχ δηλωνω μια τοπικη μεταβλητη(οχι static, ουτε global), αυτη παει και αποθηκευεται στη στοιβα..το ιδιο κι εναν πινακα αν τον δηλωσω οπως ξερουμε ως τωρα, πχεστω int aή double pin[10] Αυτο, αλλαζει αν τις μεταβλητες τις αποθηκευσω δυναμικα στο σωρο(Heap), χρησιμοποιοντας δεικτη και malloc(calloc,realloc κλπ), πχ εστω οτι για να δωσω μια τιμη σε μια μεταβλητη, ισως να το κανουμε ετσι:int *p;p=malloc(sizeof(int));*p=4;free(p);//τροπος ο οποιος μαλλον αντιπροτεινεται γτ πρεπει να εισαι ψυχακιας για να το κανεις ετσι..Η ερωτηση μου ειναι, γιατι υπαρχει αυτος ο διαχωρισμος μεταξυ σωρου και στοιβας?Ειναι, μεταξυ αλλων, για να εκμεταλευτουμε την πολυτελεια να μεταβαλουμε τα μεγεθη, πχ σε εναν πινακα, οσο τρεχει το προγραμμα μας?Επισης, διαβασα πως η σωρος μπορει να αποτυχει να δεσμευσει μνημη, επειδη πιθανον να μη βρει αρκετες διαδοχικες θεσεις μνημης τη μια διπλα στην αλλη..πχ μπορει να θελουμε να δεσμευσουμε 12 bytes και να μην μπορουμε να τα δεσμευσουμε διαδοχικα, πχ 5 bytes εδω, παρεμβαλεται αλλη δεσμευμενη μνημη στο ενδιαμεσο και μετα 7 ελευθερα bytes πιο περα (fragmented memory).Αυτο πώς μπορει να λυθει?υ.γ. Θα ειχε ενδιαφερον να λυθουν τετοιες αποριες γιατι με τετοιες γνωσεις γενικα, θεωρω πως θα μπορεσω να μπω -δυναμικα- στις δομες δεδομενων, λιστες και να εμβαθινω στη C, η οποια μου αρεσει κιολας.υ.γ. Ψαγμενοι, εμπειροι, διαβασμενοι και πιο περπατημενοι τα φωτα σας!!!!
defacer Δημοσ. 22 Μαρτίου 2016 Δημοσ. 22 Μαρτίου 2016 Η ερωτηση μου ειναι, γιατι υπαρχει αυτος ο διαχωρισμος μεταξυ σωρου και στοιβας? Για τον ίδιο λόγο που υπάρχει διαχωρισμός μεταξύ κουπέ και station wagon. Πολύ γενικά κάνουν την ίδια δουλειά (εξού και η απορία) αλλά στην πράξη το καθένα χρησιμοποιείται σε συγκεκριμένες περιπτώσεις όπου το άλλο για διάφορους λόγους θα το θεωρούσαμε ακατάλληλο. stack: super simple, super fast, αλλά η διάρκεια ζωής των αντικειμένων που αποθηκεύονται (δηλαδή, το υποσύνολο του χρόνου εκτέλεσης του προγράμματος κατά το οποίο μπορείς να αλληλεπιδράσεις με ασφάλεια) είναι αναγκαστικά "ιεραρχική". Αν το Β δημιουργηθεί στο stack χρονολογικά μετά το Α, τότε αναγκαστικά θα πρέπει και να λήξει πριν το Α. Αυτό δε βολεύει πάντα. heap: πιο περίπλοκο, πιο αργό, με μια σειρά από δικά του προβλήματα, αλλά δεν επιβάλλει απολύτως κανένα περιορισμό σχετικά με τη διάρκεια ζωής αντικειμένων. Προφανώς σε κάθε περίπτωση επιλέγεις αυτό που ταιριάζει καλύτερα στο μοντέλο χρήσης που έχεις. Ειναι, μεταξυ αλλων, [/size] για να εκμεταλευτουμε την πολυτελεια να μεταβαλουμε τα μεγεθη, πχ σε εναν πινακα, οσο τρεχει το προγραμμα μας? Όχι ακριβώς, η μεταβολή αυτή πάντα γίνεται παίρνοντας καινούριο μεγαλύτερο τμήμα μνήμης για τον πίνακα. Απλά στη μία περίπτωση (heap) η απελευθέρωση του παλιού γίνεται αμέσως αφού δε μας χρειάζεται πια ενώ στην άλλη (stack) θα γινόταν αναγκαστικά μόνο όταν "ερχόταν η ώρα της". Επισης, διαβασα πως η σωρος μπορει να αποτυχει να δεσμευσει μνημη, επειδη πιθανον να μη βρει αρκετες διαδοχικες θεσεις μνημης τη μια διπλα στην αλλη.. πχ μπορει να θελουμε να δεσμευσουμε 12 bytes και να μην μπορουμε να τα δεσμευσουμε διαδοχικα, πχ 5 bytes εδω, παρεμβαλεται αλλη δεσμευμενη μνημη στο ενδιαμεσο και μετα 7 ελευθερα bytes πιο περα (fragmented memory). Αυτο πώς μπορει να λυθει? "Δε μπορεί". Στην πράξη ο εκάστοτε memory allocator (δηλαδή, ο αλγόριθμος διαχείρισης του heap) χρησιμοποιεί μια σειρά από τεχνικές για να αποφύγει να φέρει τον εαυτό του σ' αυτή τη θέση. Αλλά τίποτα δεν είναι εγγυημένο και αν παρόλα αυτά βρεθεί σ' αυτή τη θέση τότε απλά αδυνατεί να εξυπηρετήσει. Τελείως ενδεικτικά μερικές από τις τεχνικές που χρησιμοποιούνται είναι defragmentation slab allocation memory pools τα οποία μπορείς να γκουγκλάρεις. Γενικά μιλώντας το πρόβλημα των allocators είναι πως δε μπορούν να ξέρουν απο πριν τι είδους χρήση σκοπεύεις να κάνεις εσύ στο πρόγραμμά σου. Σε πολλές περιπτώσεις όμως όπου αυτό είναι γνωστό (γιατί π.χ. μιλάμε για ένα συγκεκριμένο πρόγραμμα που έχουμε ήδη στα χέρια μας και συγκεκριμένης μορφής δεδομένα εισόδου) τότε κάποιες φορές για να πετύχουμε τη μέγιστη απόδοση γράφουμε custom allocator χρησιμοποιώντας όλες αυτές τις πληροφορίες που έχουμε. 3
nickname2016 Δημοσ. 22 Μαρτίου 2016 Μέλος Δημοσ. 22 Μαρτίου 2016 ο εκάστοτε memory allocator (δηλαδή, ο αλγόριθμος διαχείρισης του heap) Αυτος ο κυριος memory allocator, ελεγχεται απο το εκαστοτε λειτουργικο?
defacer Δημοσ. 22 Μαρτίου 2016 Δημοσ. 22 Μαρτίου 2016 Όχι, το λειτουργικό δεν ασχολείται μ' αυτά σε επίπεδο εφαρμογής. Ο βασικός allocator που χρησιμοποιείς όταν δεν ξέρεις τι είναι memory allocator παρέχεται από το runtime environment της εκάστοτε γλώσσας/τεχνολογίας. Για παράδειγμα, γράφεις ένα πρόγραμμα σε C χρησιμοποιώντας τη glibc => χρησιμοποιείς το δικό της allocator.
M2000 Δημοσ. 22 Μαρτίου 2016 Δημοσ. 22 Μαρτίου 2016 Μπορεί κάποιος να δει το σύστημα που παρέχουν τα Windows για να δίνουν μνήμη. Εδώ είναι ένα συγκριτικό για τις μεθόδους που έχουν: https://msdn.microsoft.com/en-us/library/windows/desktop/aa366533(v=vs.85).aspx
Επισκέπτης Δημοσ. 23 Μαρτίου 2016 Δημοσ. 23 Μαρτίου 2016 Για τον ίδιο λόγο που υπάρχει διαχωρισμός μεταξύ κουπέ και station wagon. Πολύ γενικά κάνουν την ίδια δουλειά (εξού και η απορία) αλλά στην πράξη το καθένα χρησιμοποιείται σε συγκεκριμένες περιπτώσεις όπου το άλλο για διάφορους λόγους θα το θεωρούσαμε ακατάλληλο. stack: super simple, super fast, αλλά η διάρκεια ζωής των αντικειμένων που αποθηκεύονται (δηλαδή, το υποσύνολο του χρόνου εκτέλεσης του προγράμματος κατά το οποίο μπορείς να αλληλεπιδράσεις με ασφάλεια) είναι αναγκαστικά "ιεραρχική". Αν το Β δημιουργηθεί στο stack χρονολογικά μετά το Α, τότε αναγκαστικά θα πρέπει και να λήξει πριν το Α. Αυτό δε βολεύει πάντα. heap: πιο περίπλοκο, πιο αργό, με μια σειρά από δικά του προβλήματα, αλλά δεν επιβάλλει απολύτως κανένα περιορισμό σχετικά με τη διάρκεια ζωής αντικειμένων. Προφανώς σε κάθε περίπτωση επιλέγεις αυτό που ταιριάζει καλύτερα στο μοντέλο χρήσης που έχεις. για να εκμεταλευτουμε την πολυτελεια να μεταβαλουμε τα μεγεθη, πχ σε εναν πινακα, οσο τρεχει το προγραμμα μας? Όχι ακριβώς, η μεταβολή αυτή πάντα γίνεται παίρνοντας καινούριο μεγαλύτερο τμήμα μνήμης για τον πίνακα. Απλά στη μία περίπτωση (heap) η απελευθέρωση του παλιού γίνεται αμέσως αφού δε μας χρειάζεται πια ενώ στην άλλη (stack) θα γινόταν αναγκαστικά μόνο όταν "ερχόταν η ώρα της". "Δε μπορεί". Στην πράξη ο εκάστοτε memory allocator (δηλαδή, ο αλγόριθμος διαχείρισης του heap) χρησιμοποιεί μια σειρά από τεχνικές για να αποφύγει να φέρει τον εαυτό του σ' αυτή τη θέση. Αλλά τίποτα δεν είναι εγγυημένο και αν παρόλα αυτά βρεθεί σ' αυτή τη θέση τότε απλά αδυνατεί να εξυπηρετήσει. Τελείως ενδεικτικά μερικές από τις τεχνικές που χρησιμοποιούνται είναι defragmentation slab allocation memory pools τα οποία μπορείς να γκουγκλάρεις. Γενικά μιλώντας το πρόβλημα των allocators είναι πως δε μπορούν να ξέρουν απο πριν τι είδους χρήση σκοπεύεις να κάνεις εσύ στο πρόγραμμά σου. Σε πολλές περιπτώσεις όμως όπου αυτό είναι γνωστό (γιατί π.χ. μιλάμε για ένα συγκεκριμένο πρόγραμμα που έχουμε ήδη στα χέρια μας και συγκεκριμένης μορφής δεδομένα εισόδου) τότε κάποιες φορές για να πετύχουμε τη μέγιστη απόδοση γράφουμε custom allocator χρησιμοποιώντας όλες αυτές τις πληροφορίες που έχουμε. defacer τι σπούδασες αν επιτρέπεται;
defacer Δημοσ. 23 Μαρτίου 2016 Δημοσ. 23 Μαρτίου 2016 defacer τι σπούδασες αν επιτρέπεται; ΗΜΜΥ. Κατα λάθος και όχι σχετικό με το θέμα αλλά τουλάχιστον μου άρεσε. 1
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα