logo

Allocation de mémoire pile ou tas

La mémoire dans un programme C/C++/Java peut être allouée sur une pile ou sur un tas.
Prérequis: Disposition de la mémoire du programme C .


Allocation de pile : L'allocation se produit sur des blocs de mémoire contigus. Nous appelons cela une allocation de mémoire de pile car l'allocation se produit dans la pile d'appels de fonction. La taille de la mémoire à allouer est connue du compilateur et chaque fois qu'une fonction est appelée, ses variables reçoivent de la mémoire allouée sur la pile. Et chaque fois que l'appel de fonction est terminé, la mémoire des variables est désallouée. Tout cela se produit à l'aide de routines prédéfinies dans le compilateur. Un programmeur n'a pas à se soucier de l'allocation de mémoire et de la désallocation des variables de pile. Ce type d'allocation de mémoire est également appelé allocation de mémoire temporaire car dès que la méthode termine son exécution, toutes les données appartenant à cette méthode sont automatiquement vidées de la pile. Cela signifie que toute valeur stockée dans le schéma de mémoire de pile est accessible tant que la méthode n'a pas terminé son exécution et est actuellement en cours d'exécution.



méthodes mathématiques en Java

Points clés:

  • Il s'agit d'un schéma d'allocation de mémoire temporaire dans lequel les données membres ne sont accessibles que si la méthode ( ) qui les contient est en cours d'exécution.
  • Il alloue ou désalloue automatiquement la mémoire dès que la méthode correspondante termine son exécution.
  • Nous recevons l'erreur Java correspondante. langue. StackOverFlowError par JVM , Si la mémoire de la pile est complètement remplie.
  • L'allocation de mémoire de pile est considérée comme plus sûre que l'allocation de mémoire de tas, car les données stockées ne sont accessibles que par le thread propriétaire.
  • L'allocation et la désallocation de mémoire sont plus rapides que l'allocation de mémoire tas.
  • La mémoire pile a moins d’espace de stockage que la mémoire tas.
C++
int main() {  // All these variables get memory  // allocated on stack  int a;  int b[10];  int n = 20;  int c[n]; }>


Allocation de tas : La mémoire est allouée lors de l'exécution des instructions écrites par les programmeurs. Notez que le nom tas n'a rien à voir avec le fuite de mémoire peut arriver dans le programme.



L'allocation de mémoire tas est divisée en trois catégories : - Ces trois catégories nous aident à prioriser les données (objets) à stocker dans la mémoire Heap ou dans le Collecte des ordures .

tuple de tri python
  • Jeune génération - C'est la partie de la mémoire où toutes les nouvelles données (objets) sont créées pour allouer de l'espace et chaque fois que cette mémoire est complètement remplie, le reste des données est stocké dans le garbage collection.
  • Génération ancienne ou titulaire – Il s'agit de la partie de la mémoire tas qui contient les objets de données les plus anciens qui ne sont pas fréquemment utilisés ou qui ne sont pas utilisés du tout.
  • Génération permanente – Il s'agit de la partie de la mémoire tas qui contient les métadonnées de la JVM pour les classes d'exécution et les méthodes d'application.

Points clés:

  • Nous recevons le message d'erreur correspondant si Heap-space est entièrement plein, Java. lang.OutOfMemoryError par JVM.
  • Ce schéma d'allocation de mémoire est différent de l'allocation d'espace de pile, ici aucune fonctionnalité de désallocation automatique n'est fournie. Nous devons utiliser un Garbage collector pour supprimer les anciens objets inutilisés afin d'utiliser efficacement la mémoire.
  • Le temps de traitement (temps d'accès) de cette mémoire est assez lent par rapport à la mémoire Stack.
  • La mémoire tas n'est pas non plus aussi sécurisée pour les threads que la mémoire pile, car les données stockées dans la mémoire tas sont visibles par tous les threads.
  • La taille de la mémoire Heap est bien plus grande que celle de la mémoire Stack.
  • La mémoire tas est accessible ou existe tant que l'ensemble de l'application (ou du programme Java) est exécuté.
RPC
int main() {  // This memory for 10 integers  // is allocated on heap.  int *ptr = new int[10]; }>

Exemple mixte des deux types d'allocation de mémoire Heap et Stack en Java :



C++
#include  using namespace std; int main() {  int a = 10; // stored in stack  int* p = new int(); // allocate memory in heap  *p = 10;  delete (p);  p = new int[4]; // array in heap allocation  delete[] p;  p = NULL; // free heap  return 0; }>
Java
class Emp {  int id;  String emp_name;  public Emp(int id, String emp_name) {  this.id = id;  this.emp_name = emp_name;  } } public class Emp_detail {  private static Emp Emp_detail(int id, String emp_name) {  return new Emp(id, emp_name);  }  public static void main(String[] args) {  int id = 21;  String name = 'Maddy';  Emp person_ = null;  person_ = Emp_detail(id, name);  } }>
Python
def main(): a = 10 # stored in stack p = None # declaring p variable p = 10 # allocating memory in heap del p # deleting memory allocation in heap p = [None] * 4 # array in heap allocation p = None # free heap return 0 if __name__ == '__main__': main()>
Javascript
// Define the Emp class with id and emp_name properties class Emp {  constructor(id, emp_name) {  this.id = id; // Initialize id  this.emp_name = emp_name; // Initialize emp_name  } } // Create an instance of the Emp class const person = new Emp(21, 'Maddy'); // Initialize person with id 21 and emp_name 'Maddy' console.log(person); // Output the person object to the console>

Voici les conclusions sur lesquelles nous tirerons après avoir analysé l’exemple ci-dessus :

date java actuelle
  • Lorsque nous commençons l'exécution du programme have, toutes les classes d'exécution sont stockées dans l'espace mémoire Heap.
  • Ensuite on retrouve la méthode main() dans la ligne suivante qui est stockée dans la pile avec toutes ses primitives (ou locales) et la variable de référence Emp de type Emp_detail sera également stockée dans la pile et pointera vers l'objet correspondant stocké dans la mémoire Heap.
  • Ensuite, la ligne suivante appellera le constructeur paramétré Emp(int, String) depuis main() et l'allouera également au sommet du même bloc de mémoire de pile. Cela stockera :
    • La référence d'objet de l'objet invoqué de la mémoire de pile.
    • La valeur primitive ( La variable de référence de l'argument String emp_name pointera vers la chaîne réelle du pool de chaînes vers la mémoire tas.
  • Ensuite, la méthode principale appellera à nouveau la méthode statique Emp_detail(), pour laquelle l'allocation sera effectuée dans le bloc de mémoire de pile au-dessus du bloc de mémoire précédent.
  • La variable de référence de l'argument String emp_name pointera vers la chaîne réelle du pool de chaînes vers la mémoire tas.
  • Ainsi, pour l'objet Emp nouvellement créé de type Emp_detail et toutes les variables d'instance seront stockées dans la mémoire tas.
  • La variable de référence de l'argument String emp_name pointera vers la chaîne réelle du pool de chaînes vers la mémoire tas.

  • Représentation picturale comme le montre la figure 1 ci-dessous :

    La variable de référence de l'argument String emp_name pointera vers la chaîne réelle du pool de chaînes vers la mémoire tas.
  • Fig. 1

    Principales différences entre les allocations de pile et de tas

    1. Dans une pile, l'allocation et la désallocation sont automatiquement effectuées par le compilateur alors que, dans un tas, elles doivent être effectuées manuellement par le programmeur.
    2. La gestion du cadre Heap est plus coûteuse que la gestion du cadre pile.
    3. Le problème de manque de mémoire est plus susceptible de se produire dans la pile, alors que le principal problème dans la mémoire tas est la fragmentation.
    4. L'accès aux trames de pile est plus facile que les trames de tas car la pile a une petite région de mémoire et est respectueuse du cache, mais dans le cas de trames de tas qui sont dispersées dans toute la mémoire, cela provoque davantage d'échecs de cache.
    5. Une pile n'est pas flexible, la taille de la mémoire allouée ne peut pas être modifiée alors qu'un tas est flexible et la mémoire allouée peut être modifiée.
    6. Accéder au temps nécessaire au tas est plus qu'une simple pile.

    Tableau de comparaison

    ParamètreEMPILERTAS
    BasiqueLa mémoire est allouée dans un bloc contigu.La mémoire est allouée dans n'importe quel ordre aléatoire.
    Allocation et désallocationAutomatique par les instructions du compilateur.Manuel par le programmeur.
    CoûtMoinsPlus
    Mise en œuvreFacileDur
    Temps d'accèsPlus rapideRalentissez
    Problème principalManque de mémoireFragmentation de la mémoire
    Localité de référenceExcellentAdéquat
    SécuritéThread-safe, les données stockées ne sont accessibles que par le propriétaireNon thread-safe, données stockées visibles par tous les threads
    La flexibilitéTaille fixeLe redimensionnement est possible
    Structure des types de donnéesLinéaireHiérarchique
    PréféréL'allocation de mémoire statique est préférable dans un tableau.L'allocation de mémoire tas est préférée dans la liste chaînée.
    TaillePetit que la mémoire tas.Plus grand que la mémoire de la pile.