Q1. En Java, tous les objets, tableaux et variables de classe sont stockés sur le tas? Est la même chose vraie pour C ++? Le segment de données est-il une partie du tas?
Qu'en est-il du code suivant en C ++? P>
void doHello(MyClass &localObj){ // 3.1 localObj is a reference parameter, where will this get stored in Heap or Stack? // do something } void doHelloAgain(MyClass localObj){ // 3.2 localObj is a parameter, where will this get stored in Heap or Stack? // do something } int main(){ MyClass *a = new MyClass(); // stored in heap MyClass localObj; // 3.3 Where is this stored in heap or stack? doHello(localObj); doHelloAgain(localObj); }
5 Réponses :
q1 strong> Java stocke également des variables sur la pile, mais des instances de classe sont allouées sur le tas. En C ++, vous êtes libre d'attribuer vos instances de classe sur la pile ou sur le tas. En utilisant le mot-clé Le segment de données ne fait pas partie du tas, mais est alloué lorsque le processus commence. Le tas est utilisé pour des allocations de mémoire dynamiques, tandis que le segment de données est statique et le contenu est connu à l'heure de la compilation. P> Le segment BSS est simplement une optimisation dans laquelle toutes les données appartenant au segment de données (par exemple, String, numéros constants, etc.) qui ne sont pas initialisés ou initialisés à zéro sont déplacés vers le segment BSS. Le segment de données doit être incorporé dans l'exécutable et en déplaçant "tous les zéros" à la fin, ils peuvent être retirés de l'exécutable. Lorsque l'exécutable est chargé, le segment BSS est attribué et initialisé à zéro, et le compilateur est toujours capable de connaître les adresses des différents tampons, variables, etc. à l'intérieur du segment BSS. P> comme Cependant, vous pouvez affecter q3 fort> p> Lorsque vous appelez Lorsque vous appelez neuf code>, vous allouez l'instance sur le tas. P>
myClass :: Number code> est stocké lorsque l'instance de
myClass code> est attribuée. Cela pourrait être sur le tas ou sur la pile. AVIS DANS Q3 Comment
A CODE> Points à une instance de
MyClass Code> attribué sur le tas tandis que
localobj code> est attribué sur la pile. Ainsi,
a-> numéro code> est situé sur le tas lorsque
localobj.number code> est situé sur la pile. P>
myClass :: Number < / Code> est une variable d'instance que vous ne pouvez pas l'affecter comme ceci: p>
myClass :: compteur code> telle qu'elle est statique ( Sauf que c'est privé): p>
DOHELLO code> la variable
localobj code> (dans
principal code>) est passé par référence. La variable
localobj code> in
Dohello code> renvoie à cette variable sur la pile. Si vous modifiez cela, les modifications seront stockées sur la pile où
localobj code> dans
principal code> est alloué. P>
DOHELLOAGAIN CODE > La variable
localobj code> (dans
principal code>) est copiée sur la pile. Intérieur
Dohelloagain Code> La variable
localobj code> est allouée sur la pile et n'existe que pendant la durée de l'appel. P> p>
Q3: Les références, comme les pointeurs, sont des valeurs 32 bits (généralement) qui contiennent une adresse mémoire. Cela va sur la pile à Dohello. La classe "MyInstance" est de 8 octets (en supposant que INT est 32 bits), et cela va sur la pile de Dohelloagain.
Q1. En Java, tous les objets, les tableaux et Les variables de classe sont stockées sur le tas? Est la même chose vraie pour C ++? Est segment de données une partie de tas? p>
Non, la section de données est séparée du tas. Fondamentalement, la section de données est allouée à temps de charge, tout ce qu'il existe un emplacement fixe après cela. De plus, des objets peuvent être alloués sur la pile. P>
Les seuls objets de temps sont sur le tas, c'est si vous utilisez le mot-clé
neuf code> ou si vous utilisez quelque chose dans le
malloc code> famille de fonctions. P>
Q2. En ce qui précède mon compréhension, variables qui reçoivent un spécifique la valeur par compilateur sont stockées dans des données segment et inticulé global et Les variables statiques sont stockées dans BSS (Bloc démarré par le symbole). Dans ce Cas, MyInstance :: Counter Statique est initialisé à zéro par le compilateur et donc il est stocké chez BSS et MyInstance :: Numéro qui est initialisé à 100 est stocké dans la segment de données. Ai-je raison de faire la conclusion? P> BlockQuote>
Oui, votre compréhension de la section BSS est correcte. Cependant, étant donné que
numéro code> n'est pas statique le code: p>
xxx pré> n'est pas légal, il doit être soit fait statique, soit initialisé dans le constructeur correctement. Si vous l'initialisez dans le constructeur, il existera partout où l'objet de possession est attribué. Si vous le faites statique, cela se retrouvera dans la section de données ... Si n'importe où. Souvent
statique const int code> variables peut être inlincé directement dans le code utilisé de manière à ce qu'une variable globale ne soit pas nécessaire du tout. P>
Q3. Pensez à suivre les codes suivants: ... p> BlockQuote>
Void Dohello (MyInstance & localobj) { Code> P>
localobj est une référence à l'objet transmis. Pour autant que vous sachiez, il n'y a pas de stockage, il fait référence à l'endroit où la variable est passée est. En réalité, sous la hotte, un pointeur peut être transmis sur la pile pour faciliter cela. Mais le compilateur peut tout aussi facilement optimiser cela si cela peut. P>
Void Dohelloagain (myInstance localobj) { code> p>
A forte> > du paramètre transmis est placé sur la pile. p>
xxx pré> localobj est sur la pile. p> blockquote>
"Les objets peuvent être alloués sur la pile" Je suis d'accord avec ça, mais est-ce la même chose en cas de Java?
Non, Java attribue uniquement des primitives et des références sur la pile, pas des objets.
en C ++, des objets peuvent être alloués sur la pile ... Par exemple, localobj dans votre routine principale Q3. P>
Je sens une certaine confusion sur les classes par rapport aux cas. "MyInstance" a plus de sens comme nom de variable qu'un nom de classe. Dans votre exemple Q1, "numéro" est présent dans chaque objet de type myInstance. "Compteur" est partagé par toutes les instances. "MyInstance :: compteur = 100" est une affectation valide, mais "myInstance :: Number = 100" n'est pas, car vous n'avez pas spécifié quel objet devrait avoir son membre "nombre" attribué à. p>
Ceci est un peu simplifié mais surtout précis au meilleur de ma connaissance. P>
En Java, tous les objets sont alloués sur le tas (y compris toutes vos variables de membre). La plupart des autres choses (paramètres) sont des références et les références elles-mêmes sont stockées sur la pile ainsi que des types natifs (INTS, LIPS, etc.), à l'exception de la chaîne qui est plus d'un objet qu'un type natif. P>
en C ++, si vous alliez allouer tous les objets avec le mot-clé "Nouveau", il serait à peu près la même situation que Java, mais il y a un cas unique en C ++, car vous pouvez allouer des objets sur la pile (vous ne pouvez pas 't toujours avoir à utiliser "nouveau"). p>
Notez également que les performances du tas de Java sont plus proches de la performance de la pile de C que de C de la performance du tas de C, le collecteur des ordures fait des trucs assez intelligents. Ce n'est toujours pas aussi bon que la pile, mais bien mieux qu'un tas. Ceci est nécessaire car Java ne peut pas allouer des objets sur la pile. P>
De belles informations sur la performance du tas de Java et la comparaison de performances de la pile de C
Tous les objets Java sont stockés dans le tas, oui. Les variables d'objet stockent les références. Les variables primitives (int, flotteur, bool, etc.) stockent leurs propres valeurs; Ce ne sont pas des références. Les paramètres de la méthode sont passés par la valeur.
À ce stade, je méprise vraiment toute la réussite par la terminologie de valeur / de référence et essayez de ne pas l'utiliser. En Java, il est plus facile de rappeler que lorsque vous traitez avec des objets, vous avez toujours une référence, vous ne transmettez jamais l'objet réel. Pour dire que cela n'est pas "Pass par référence" confond à l'enfer de quiconque tente de comprendre comment la langue fonctionne (même si c'est vrai), donc j'ai complètement abandonné la terminologie.
@Devil Jin Yeah, la façon dont Java, l'allocation de tas ne nécessite aucune action par répartition pour libérer la mémoire pour des objets de courte durée (ce qui est juste la manière de la répartition de la pile - un seul "retour" apparaît tous les objets de la pile à une fois). Il y a des papiers blancs qui font de très belles lectures.
Chaque fois que vous appelez
nouveau code>, vous êtes mallocing, ce qui signifie que tout ce que vous créez avec
nouveau code> est bien stocké sur le tas. Je n'ai aucune idée de ce que vous entendez par "Le segment de données est une partie du tas?".
MyClass :: Numéro = 100; ne compilera pas. Avez-vous voulu compter contre?
Numéro de variable modifié des membres à statique