1
votes

Java Multi-threading - Pourquoi avons-nous besoin de regarder dans la mémoire principale (RAM) si nous avons partagé le tas?

Si nous appliquons un mot-clé volatile, les threads lisent depuis la mémoire principale au lieu de son propre cache. Si nous avons une mémoire de tas commune, pourquoi devons-nous examiner la mémoire principale? Voulons-nous dire que la mémoire principale (RAM) et le tas sont identiques?


4 commentaires

Chaque thread dispose d'une copie des données du tas pour des raisons de performances. En utilisant la force volatile, il regarde dans le tas, au cas où un autre thread modifierait cet objet qui est partagé entre de nombreux threads. C'est une question très large, pourriez-vous donner un exemple pour lequel vous avez besoin d'aide?


Le tas de la JVM réside dans la mémoire principale.


FWIW: Il n'y a pas de "mémoire principale" ou de "cache" dans le langage Java. Ce sont des détails de mise en œuvre. La spécification du langage Java ne parle que des champs d'objet et des variables statiques et les règles qui régissent le moment où (le cas échéant) une mise à jour de l'un de ceux par un thread deviendra visible par un autre thread.


L'utilisation de volatile ne force pas la lecture à partir de la mémoire principale. En théorie, l'utilisation de processeurs volatils pouvait lire indéfiniment à partir du cache; les caches sont la source de la vérité .. ils ne seront jamais désynchronisés.


3 Réponses :


0
votes

Si nous avons une mémoire de tas commune, pourquoi avons-nous besoin de regarder dans la mémoire principale?

Le tas Java est stocké dans la mémoire principale de l'ordinateur.

Les autres éléments stockés dans la mémoire principale sont les piles de threads, la zone de méthode et le pool de constantes. Celles-ci sont présentées dans la section 2.5 des spécifications JVM https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html#jvms-2.5


0 commentaires

2
votes

Il y a deux aspects à cette question.

tas / RAM / mémoire principale

Dans ce contexte, les termes RAM et mémoire principale font référence à la même chose. Je dirai RAM dans le reste de cet article. Ces termes ont un sens au niveau matériel et au niveau logiciel. Heap est un terme utilisé au niveau logiciel uniquement pour désigner une zone RAM dans laquelle des objets peuvent être créés.

Au niveau logiciel, outre le tas, il y a la pile. La pile est également une zone de mémoire dans la RAM. En java, la pile ne peut contenir que des types de données primitifs comme int ou long, et des pointeurs (adresses mémoire) vers des objets, qui sont à l'intérieur du tas.

Au niveau matériel, invisible pour le programmeur, il existe un certain nombre de caches mémoire pour la mise en cache des données fréquemment réutilisées. Cela accélère le fonctionnement de l'ordinateur, car les accès à la mémoire prennent moins de temps. Dans presque tous les cas, en tant que programmeur, vous ne verrez ces caches nulle part. Vous ne pouvez remarquer des gains de performances que dans certains cas particuliers.
Lorsque plusieurs cœurs de processeur (pensez aux threads) accèdent à la même adresse mémoire dans la RAM, les données auxquelles ils accèdent peuvent en fait provenir d'un cache entre la RAM et le CPU. Si une variable n'est pas marquée comme volatile, alors ces caches peuvent contenir des données différentes, et donc différents cœurs de processeur recevront des données différentes pour la même adresse mémoire. Ceci est, très souvent, indésirable. Pour cela, le mot clé volatile existe. Si vous marquez une variable comme volatile, les cœurs de processeur s'assurent qu'ils lisent directement à partir de la RAM et mettent à jour la mémoire réécrit dans la RAM pour s'assurer que les autres cœurs de processeur peuvent accéder à la valeur à jour.


6 commentaires

L'utilisation de volatile ne force pas la lecture à partir de la mémoire principale. C'est une idée fausse. Sur les caches X86 sont toujours cohérents. Il ne peut donc pas arriver que vous lisiez des données obsolètes à partir d'un cache. Il se peut que la mémoire ne soit pas synchronisée avec le cache ... c'est bien ... Le cache est la source de vérité ... la mémoire principale ne l'est pas.


@pveentjer cela semble très intéressant. Pouvez-vous nous en dire plus, s'il vous plaît, et peut-être publier des liens?


Si vous souhaitez approfondir: morganclaypool.com/doi/abs/10.2200/S00962ED2V01Y201910CAC049


@pveentjer c'est un livre de 300 p. Je suis sûr qu'il y a une partie spécifique du livre que vous aviez à l'esprit lors de la publication du lien, non?


Les premiers chapitres vous donnent la plupart des bases, y compris un chapitre d'introduction relativement court sur la cohérence du cache qui pourrait répondre à vos questions.


Oui je l'ai fait. Je n'ai pas parcouru tout le livre, mais j'ai passé pas mal de temps dans les premiers chapitres.



0
votes

Si nous appliquons un mot-clé volatile, les threads lisent depuis la mémoire principale au lieu de son propre cache.

Ce n'est pas correct. La variable volatile s'assure qu'il se produit un front avant entre une écriture de cette variable et toute lecture ultérieure de cette variable. Et cela entraîne une cohérence séquentielle de l'accès. Si vous avez 2 accès conflictuels (2 threads accédant à la même adresse et au moins l'un d'entre eux est une écriture) et que ces accès conflictuels ne sont pas ordonnés par un arrive avant le bord, alors vous avez une course aux données et avec les courses de données, le comportement du programme est indéfini.

Vous ne devriez pas penser en termes de mémoire principale et de caches; pensez en termes de modèle de mémoire Java et dans ce cas de la règle de variable volatile. Les caches sont toujours cohérents sur le X86; il n'est donc pas possible de lire des données obsolètes à partir d'un cache.

Pour info: la RAM est une mémoire partagée entre tous les processeurs. Heap est une utilisation de la RAM, tout comme les piles. En Java, les objets sont généralement créés sur le tas (je ne connais aucune implémentation JVM d'allocation basée sur la pile; seulement le remplacement scalaire).


0 commentaires