8615 votes

Quoi et où sont de la pile et le tas?

Langage de programmation livres expliquent généralement que les types de valeur sont créés sur la pile, et les types de référence sont créés sur le tas, sans vraiment expliquer ce que ces deux choses sont. Avec ma seule expérience de la programmation en cours dans les langues, je n'ai pas lu une explication claire de ce. Je veux dire, je comprends ce qu' une pile est, mais où et quels sont-ils (par rapport à la mémoire physique de l'ordinateur)?

  • Dans quelle mesure sont-ils contrôlés par le système d'exploitation ou d'exécution de langue?
  • Quelle est leur portée?
  • Ce qui détermine la taille de chacun d'eux?
  • Ce qui est plus rapide?

6352voto

Jeff Hill Points 22158

La pile de la mémoire est mis de côté comme espace de travail pour un thread d'exécution. Quand une fonction est appelée, un bloc est réservé, sur le haut de la pile pour les variables locales et certains de comptabilité de données. Lorsque cette fonction est de retour, le bloc devient non utilisés et peuvent être utilisés la prochaine fois qu'une fonction est appelée. La pile est toujours réservé dans un PRINCIPE de l'ordre, le plus récemment réservés bloc est toujours le prochain bloc à être libéré. Cela rend très simple de garder une trace de la pile; la libération d'un bloc à partir de la pile n'est rien de plus que d'adapter un pointeur.

Le segment de mémoire de la mémoire est mis de côté pour l'allocation dynamique. Contrairement à la pile, il n'y a pas forcée de modèle pour l'allocation et la désallocation de blocs dans le tas; vous pouvez allouer un bloc à tout moment et gratuitement à tout moment. Cela le rend beaucoup plus complexe pour garder une trace de la part du segment de mémoire sont alloués ou libre à un moment donné; il y a beaucoup de custom tas allocateurs disponibles pour accorder tas de performance pour les différents modes d'utilisation.

Chaque fil est une pile, tandis que il ya généralement un seul segment de l'application (bien qu'il n'est pas rare d'avoir plusieurs tas de différents types de répartition).

Pour répondre à vos questions directement:

Dans quelle mesure sont-ils contrôlés par le système d'exploitation ou d'exécution de langue?

Le système d'exploitation alloue de la pile pour chaque niveau du système de thread lorsque le thread est créé. Généralement, le système d'exploitation est appelé par le language runtime pour allouer le tas pour l'application.

Quelle est leur portée?

La pile est connectée à un fil, de sorte que lorsque le fil sort de la pile est récupérée. Le tas est généralement attribuées au démarrage de l'application par le moteur d'exécution, et est récupérée lors de l'application (techniquement processus) sorties.

Ce qui détermine la taille de chacun d'eux?

La taille de la pile est définie lors de la création d'un thread. La taille du segment de mémoire est définie de démarrage de l'application, mais ne peut croître que l'espace est nécessaire (le processus d'allocation des demandes de plus de la mémoire du système d'exploitation).

Ce qui est plus rapide?

La pile est plus rapide parce que le modèle de l'accès rend banal d'allouer et de libérer de la mémoire (un pointeur d'entier est tout simplement incrémenté ou décrémenté), tandis que le tas est beaucoup plus complexe comptabilité impliqués dans une allocation ou gratuit. Aussi, chaque octet dans la pile tend à être réutilisé, très fréquemment, ce qui signifie qu'il a tendance à être mappé sur le processeur, la mémoire cache, qui le rend très rapide. Un autre gain de performance pour le segment est le segment de mémoire, étant la plupart du temps une ressource mondiale, a généralement à être multi-threading sûr, c'est à dire chaque allocation et la libération doit être généralement synchronisé avec "tous" les autres tas accède au programme.

Une démonstration claire:


Source de l'Image: vikashazrati.wordpress.com

2482voto

Brian R. Bondy Points 141769

Pile:

  • Stockées dans la mémoire RAM de l'ordinateur comme le tas.
  • Les Variables créé sur la pile hors de portée et automatiquement désallouer.
  • Beaucoup plus rapide à allouer dans la comparaison des variables sur le tas.
  • Mis en œuvre avec un tapis de structure de données.
  • Les magasins de données locales, des adresses de retour, utilisé pour la transmission de paramètres
  • Peut avoir un débordement de la pile lorsque trop de la pile est utilisée. (principalement à partir de l'infini (ou trop) de récursivité, de très grandes affectations)
  • Les données créées sur la pile peut être utilisée sans les pointeurs.
  • Vous devez utiliser la pile si vous savez exactement combien de données vous avez besoin d'allouer avant le moment de la compilation, et il n'est pas trop grand.
  • Habituellement, la taille maximum est déjà déterminé quand au début de votre programme

Tas:

  • Stockées dans la mémoire RAM de l'ordinateur comme la pile.
  • Les Variables sur le tas doit être détruit manuellement et ne jamais tomber hors de portée. Les données sont libérées avec delete, delete[] ou libre
  • Plus lent à allouer dans la comparaison de variables sur la pile.
  • Utilisé sur la demande d'allouer un bloc de données utilisées par le programme.
  • Peut avoir une fragmentation lorsqu'il y a beaucoup d'allocations et de deallocations
  • En C++ les données créées sur le tas sera souligné par des pointeurs et affectées avec de nouveaux ou de malloc
  • Peut avoir des échecs d'allocation si un trop grand d'un tampon est demandé à être affecté.
  • Vous utilisez le tas si vous ne savez pas exactement combien de données vous aurez besoin lors de l'exécution ou si vous avez besoin d'allouer une grande quantité de données.
  • Responsable des fuites de mémoire

Exemple:

int foo()
{
  char *pBuffer; //<--nothing allocated yet (excluding the pointer itself, which is allocated here on the stack).
  bool b = true; // Allocated on the stack.
  if(b)
  {
    //Create 500 bytes on the stack
    char buffer[500];

    //Create 500 bytes on the heap
    pBuffer = new char[500];

   }//<-- buffer is deallocated here, pBuffer is not
}//<--- oops there's a memory leak, I should have called delete[] pBuffer;

1421voto

thomasrutter Points 42905

Le point le plus important est que le tas et la pile sont des termes génériques pour les façons dont la mémoire peut être affecté. Ils peuvent être mis en œuvre dans de nombreuses façons différentes, et les conditions s'appliquent les concepts de base.

  • Dans une pile d'éléments, les éléments s'asseoir les uns sur les autres dans l'ordre où ils ont été placés là, et vous ne pouvez enlever le haut (sans le renversement de l'ensemble de la chose).

    Stack like a stack of papers

  • Dans un tas, il n'y a pas d'ordre particulier à la manière dont les éléments sont placés. Vous pouvez atteindre dans et supprimer des éléments dans n'importe quel ordre, car il n'est pas clair " top " de l'élément.

    Heap like a heap of licorice allsorts

Il fait un assez bon travail de décrire les deux façons de faire de l'allocation et de libération de la mémoire dans une pile et un tas. Miam!!!

  • Dans quelle mesure sont-ils contrôlés par le système d'exploitation ou d'exécution de langue?

    Comme mentionné, du tas et de la pile sont des termes généraux, et peut être mis en œuvre dans de nombreuses façons. Des programmes informatiques ont généralement une pile appelée une pile d'appel qui stocke les informations pertinentes à la fonction actuelle comme un pointeur vers quelle fonction il a été appelé, et les variables locales. Parce que les fonctions d'appel autres fonctions, et puis le retour, la pile grandit et rétrécit à retenir des informations sur les fonctions de plus bas dans la pile d'appel. Un programme n'a pas vraiment d'exécution le contrôle; il est déterminé par le langage de programmation, système d'exploitation et même de l'architecture du système.

    Un tas est un terme général utilisé pour la mémoire est allouée dynamiquement et de façon aléatoire; c'est à dire de l'ordre. La mémoire est généralement alloué par le système d'exploitation, avec l'application de l'appel de l'API des fonctions pour effectuer cette répartition. Il est un peu juste des frais généraux nécessaires à la gestion de la mémoire allouée dynamiquement, ce qui est généralement géré par le système d'exploitation.

  • Quelle est leur portée?

    La pile d'appel est d'un niveau tellement bas concept qu'il ne concerne pas la "portée" dans le sens de la programmation. Si vous démontez un peu de code, vous verrez relative pointeur style des références à des portions de la pile, mais autant que d'un langage de plus haut niveau, la langue impose ses propres règles de portée. Un aspect important d'une pile, cependant, est qu'une fois qu'une fonction retourne une valeur, quelque chose locale à cette fonction est immédiatement libéré à partir de la pile. Qui fonctionne de la même façon que vous attendez qu'il fonctionne à la façon dont vos langages de programmation le travail. Dans un tas, c'est aussi difficile à définir. La portée est tout ce qui est exposé par l'OS, mais votre langage de programmation probablement ajoute ses règles sur ce qu'est une "portée" est dans votre application. L'architecture du processeur et l'utilisation du système d'exploitation virtuel de l'adressage, le processeur se traduit par une adresse physique et il y a des défauts de page, etc. Ils gardent la trace de ce que les pages qui appartiennent à des applications. Vous n'avez jamais vraiment besoin de s'inquiéter à ce sujet, bien que, parce que vous venez d'utiliser quelle que soit la méthode de votre langage de programmation utilise pour allouer et de libérer de la mémoire, et de vérifier les erreurs (si l'allocation/libération de échoue pour une raison quelconque).

  • Ce qui détermine la taille de chacun d'eux?

    Encore une fois, cela dépend de la langue, compilateur, système d'exploitation et l'architecture. Une pile est généralement pré-alloué, parce que, par définition, il doit être contigu de mémoire (plus que dans le dernier paragraphe). Le compilateur de langage ou de l'OS de déterminer sa taille. Vous n'avez pas stocker d'énormes morceaux de données sur la pile, donc ça va être assez grand pour que l'on ne devrait jamais être utilisé en totalité, sauf dans les cas de non désirées récursivité sans fin (d'où, "stack overflow") ou d'autres inhabituel que les décisions de programmation.

    Un tas est un terme général pour tout ce qui peut être alloué dynamiquement. Selon la façon dont vous le regardez, il est constamment l'évolution de la taille. Dans les processeurs modernes et des systèmes d'exploitation de la manière exacte dont cela fonctionne est très abstraites de toute façon, vous n'avez normalement pas besoin de s'inquiéter beaucoup sur la façon dont il fonctionne au fond, sauf que (dans des langues où il vous permet de vous) vous ne devez pas utiliser la mémoire que vous n'avez pas alloué ou encore de la mémoire que vous avez libéré.

  • Ce qui est plus rapide?

    La pile est plus rapide car tous les libérer de la mémoire est toujours contigus. Pas de liste doit être maintenue de tous les segments de mémoire libre, un seul pointeur vers le haut actuel de la pile. Les compilateurs généralement de stocker le pointeur this dans une spéciale rapide, vous inscrire à cette fin. De plus, les opérations suivantes sur une pile est habituellement concentrée à proximité des zones de mémoire, qui, à un niveau très faible, ce qui est bon pour l'optimisation par le processeur à die caches.

762voto

Martin Liversage Points 43712

(J'ai déplacé cette réponse à partir d'une autre question qui a été plus ou moins dupe de celui-ci.)

La réponse à votre question est mise en œuvre spécifique et peuvent varier à travers les compilateurs et les architectures de processeur. Cependant, voici une explication simplifiée.

  • À la fois la pile et le tas sont des zones de mémoire allouées à partir du sous-jacent système d'exploitation (souvent de la mémoire virtuelle qui est mappé à la mémoire physique sur demande).
  • Dans un environnement multi-thread chaque thread a son propre complètement indépendant de la pile, mais ils vont partager le tas. L'accès simultané doit être contrôlée sur le tas et n'est pas possible sur la pile.

Le tas

  • Le tas contient une liste liée de servir et de blocs libres. Les nouvelles allocations sur le tas (en new ou malloc) sont satisfaits par la création d'une cale appropriée à partir de l'un des blocs libres. Cela nécessite la mise à jour de la liste des blocs sur le tas. Cette méta-informations sur les blocs sur le tas est également stockée sur le tas, souvent, dans une petite zone située juste en face de chaque bloc.
  • Comme le tas croît de nouveaux blocs sont souvent affectés de la baisse des adresses vers des adresses. Ainsi, vous pouvez penser à des tas comme un tas de blocs de mémoire qui augmente la taille de la mémoire est allouée. Si le tas est trop petit pour une répartition de la taille peut souvent être augmentée par l'acquisition de plus de mémoire à partir du sous-jacent système d'exploitation.
  • L'allocation et la désallocation de nombreux petits blocs peuvent quitter le tas dans un état où il y a beaucoup de petits blocs libres intercalés entre les blocs utilisés. Une demande d'allouer un gros bloc peut échouer, car aucun des blocs libres sont assez grand pour satisfaire la demande d'allocation, même si la taille combinée des blocs libres peuvent être assez grande. Cela s'appelle la fragmentation du segment.
  • Lorsqu'un bloc adjacent à un bloc libre est libéré le bloc libre peut être fusionné avec le côté bloc libre pour créer un plus grand bloc libre efficace de réduire la fragmentation du tas.

The heap

La pile

  • La pile travaille souvent en étroite tandem avec un registre spécial sur le CPU nommé le pointeur de pile. Initialement, le pointeur de pile pointe vers le haut de la pile (la plus haute de l'adresse sur la pile).
  • La CPU a des instructions spéciales pour les poussant des valeurs sur la pile et sautant en arrière à partir de la pile. Chaque pousser les magasins de la valeur à l'emplacement actuel du pointeur de pile et diminue le pointeur de pile. Un pop récupère la valeur pointée par le pointeur de pile, puis augmente le pointeur de pile (ne pas être confondu par le fait que l'ajout d' une valeur dans la pile diminue le pointeur de pile et de retrait d' une valeur augmente . Rappelez-vous que la pile grandit vers le bas). Les valeurs stockées et récupérées sont les valeurs des registres du CPU.
  • Quand une fonction est appelée, le PROCESSEUR utilise les instructions spéciales que pousser le courant pointeur d'instruction, c'est à dire l'adresse de l'exécution de code sur la pile. Le CPU accède ensuite à la fonction de réglage de la pointeur d'instruction à l'adresse de la fonction appelée. Plus tard, lorsque la fonction retourne, la vieille pointeur d'instruction est sorti de la pile et l'exécution reprend le code juste après l'appel à la fonction.
  • Lorsqu'une fonction est entré, le pointeur de pile est réduite à allouer plus d'espace sur la pile pour les locaux (automatique) des variables. Si la fonction a un local 32 bits variable de quatre octets sont mis de côté sur la pile. Lorsque la fonction retourne le pointeur de pile est déplacée vers l'arrière pour libérer la zone allouée.
  • Si une fonction a des paramètres, ceux-ci sont poussés sur la pile avant l'appel à la fonction. Le code de la fonction est alors en mesure de naviguer vers le haut de la pile de l'actuel pointeur de pile pour localiser ces valeurs.
  • L'imbrication des appels de fonction de travail comme un charme. Chaque nouvel appel d'allouer les paramètres de la fonction, l'adresse de retour et de l'espace pour les variables locales et ces activation enregistrements peuvent être empilés pour les appels imbriqués et se détendre dans la bonne voie quand le retour des fonctions.
  • Comme la pile est limitée bloc de mémoire, vous pouvez provoquer un débordement de pile en appelant le trop grand nombre de fonctions imbriquées et/ou de l'allocation de trop de place pour les variables locales. Souvent, la zone de mémoire utilisée pour la pile est définie de telle sorte que l'écriture ci-dessous le bas (l'adresse la plus basse) de la pile sera le déclencheur d'un piège ou d'une exception dans le CPU. Cet état exceptionnel, ils peuvent ensuite être pris par le moteur d'exécution et converti en une sorte d'exception de dépassement de pile.

The stack

Peut être alloué sur le tas au lieu d'une pile?

Non, l'activation des enregistrements pour les fonctions (à l'échelle locale ou variables automatiques) sont allouées sur la pile qui est utilisé non seulement pour stocker ces variables, mais aussi pour garder la trace d'imbrication des appels de fonction.

Comment le tas est géré est vraiment à l'environnement d'exécution. C utilise malloc et C++ utilise new, mais de nombreuses autres langues ont de collecte des ordures.

Cependant, la pile est un plus faible niveau de fonctionnalité étroitement liée à l'architecture du processeur. Croissance le tas lorsqu'il n'y a pas assez d'espace n'est pas trop dur, car il peut être mis en œuvre dans l'appel de la bibliothèque qui gère le tas. Cependant, la croissance de la pile est souvent impossible, ainsi que le débordement de la pile seulement est découvert quand il est trop tard; et l'arrêt du thread d'exécution est la seule option viable.

423voto

Snow Crash Points 6429

Cela permet de:

enter image description here

Fixe la taille des objets (comme un int et lc1 (le pointeur d'objet de référence)) aller sur la pile 'cos nous savons de leur taille.

[Remarque, j'avais utilisé l'expression des éléments statiques qui pouvait induire en erreur, parce que certaines personnes lorsque l'interprétation, il s'agit des variables statiques. J'ai changé la phrase de taille fixe pour être plus clair.]

Les objets (qui varient en taille, comme nous le mettre à jour) aller sur le tas 'cos nous ne savons pas leur taille.

Pour résumer, si vous connaissez la taille de la variable (par exemple un int), il va sur la pile. Si non, il va sur le tas. Et des objets toujours, toujours, toujours aller sur le tas.

Plus d'informations peuvent être trouvées ici:

La différence entre la pile et le tas de l'allocation de mémoire « timmurphy.org

et ici:

Création d'Objets sur la Pile et le Tas

Cet article est la source de la photo ci-dessus: Six importante .NET concepts: Pile, tas, la valeur des types, des types de référence, de la boxe, et unboxing - CodeProject

mais sachez qu'il peut contenir quelques erreurs.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X