66 votes

Un simple "Hello World" nécessite 10G de mémoire virtuelle sur une machine 64-bit contre 1G en 32-bit ?

En exécutant un simple programme Java sur notre machine de production, j'ai remarqué que ce programme consomme plus de 10G de virt. Je sais que la mémoire virtuelle n'est pas si importante, mais j'aimerais au moins comprendre pourquoi elle est nécessaire.

public class Main {
  public static void main(String[] args) {
        System.out.println("Hello World!");
        try {
                Thread.sleep(10000);
        } catch(InterruptedException e) {
                /* ignored */
        }
  }
}

Voici ce que top dit quand je lance ce petit programme :

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
18764 myuser    20   0 10.2g  20m 8128 S  1.7  0.1   0:00.05 java

Quelqu'un sait-il pourquoi cela se produit ?

uname -a dit :

Linux m4fxhpsrm1dg 2.6.32-358.18.1.el6.x86_64 #1 SMP Fri Aug 2 17:04:38 EDT 2013 x86_64 x86_64 x86_64 GNU/Linux

Sur une ancienne machine 32bit-linux, le même programme ne consomme qu'environ 1G de virt. L'ancienne machine dispose de 4 Go de RAM, la nouvelle de 32 Go.

86voto

Michael Borgwardt Points 181658

El tailles par défaut pour le tas initial et le tas maximum sont définies comme un pourcentage de la mémoire physique de la machine, dont un serveur de production a aujourd'hui tendance à avoir beaucoup .

Vous pouvez choisir les deux via le Options de ligne de commande -Xms et -Xmx .

46voto

Luaan Points 8934

La mémoire virtuelle n'a pas vraiment d'importance pour vous.

La différence fondamentale entre 32 et 64 bits est que l'espace d'adressage en 64 bits est incroyablement grand. Si 10 Go vous semblent beaucoup, sachez que .NET en 64 bits peut utiliser des TiBs de mémoire comme celui-ci. En 32 bits, .NET est beaucoup plus conservateur (tout comme la JVM) - l'espace d'adressage est de 4 Go. total - ce n'est pas beaucoup.

Mais c'est sans importance - ça n'a pas d'importance. C'est juste une chose qui simplifie grandement la programmation, et qui n'a aucun effet négatif sur le système d'exploitation hôte. Il crée un espace d'adressage continu pour la VM, ce qui signifie que vous n'avez pas besoin de fragmenter le tas (ou pire, la pile, où c'est plus ou moins impossible - mais ils ont tendance à être seulement un MiB ou plus) lorsque vous avez besoin de plus de mémoire "réelle". Lorsque vous engagez finalement la mémoire virtuelle, elle devient légèrement plus réelle - à ce moment, elle doit plus ou moins être soutenue par un peu de le stockage des données - que ce soit le fichier de page (swap) ou la RAM physique.

En fait, l'emplacement physique de la mémoire n'est pas nécessairement continu, mais cela se fait hors de votre portée, et le mappage est généralement très rapide. D'un autre côté, devoir, disons, indexer un tableau, qui est en fait fragmenté sur 10 blocs de mémoire d'adresse virtuelle différents, c'est un travail (complètement inutile).

Vous l'avez compris, la mémoire virtuelle est presque libre sur 64 bits. L'approche de base est "si elle est là, utilisez-la". Vous ne limitez pas les autres applications, et cela vous permet d'économiser pas mal de travail si vous hacer finissent par l'utiliser. Mais jusqu'à ce que ce moment arrive, vous n'avez qu'une réservation. Cela ne se traduit pas du tout par une mémoire physique. Vous ne payez pas pour les amis qui pourraient venir ce soir s'asseoir à votre table, mais vous avez toujours l'espace pour qu'ils puissent s'asseoir s'ils viennent - et ce n'est que lorsqu'ils viennent enfin que vous êtes réellement "facturé".

Voir cette question pour plus d'informations sur la façon dont Java se comporte sur différentes machines et avec différentes versions : http://stackoverflow.com/questions/2915276/what-is-the-default-maximum-heap-size-for-suns-jvm-from-java-se-6 La taille maximale du tas détermine également la quantité de mémoire virtuelle réservée, car le tas doit être un espace d'adressage continu. S'il n'était pas pré-réservé, il pourrait arriver que le tas ne puisse pas s'étendre jusqu'à cette valeur maximale, parce que quelqu'un d'autre a réservé une région de l'espace d'adressage à l'endroit où le tas doit s'étendre.

8voto

thomasrutter Points 42905

Il s'avère que sur une architecture d'ordinateur moderne qui utilise l'adressage de la mémoire virtuelle (où l'"espace mémoire" que voit une application ne correspond pas réellement à la mémoire qui se trouve sur le disque dur de l'ordinateur), il n'y a pas d'espace mémoire. en fait physiquement allouée), la quantité de cet "espace mémoire" virtuel donnée à une application au démarrage n'a pas vraiment d'importance. Cela ne signifie pas que cette quantité de mémoire a été allouée par le système.

Si une application voit un espace d'adressage virtuel de 10 Go de large, tout ce que cela lui signale est qu'elle mai utiliser des adresses mémoire jusqu'à 10 Go si elle le souhaite. Cependant, la mémoire n'est pas réellement allouée dans la RAM physique tant qu'elle n'a pas été écrite, et cela se fait page par page, une page étant une section de mémoire de 4 Ko. L'espace d'adressage virtuel est tout simplement virtuel jusqu'à ce qu'il soit réellement utilisé.

Disons qu'une application se voit attribuer 10 Go d'espace d'adressage et qu'elle commence à en utiliser une partie. Lors de la première écriture d'une page "fraîche" de cette mémoire virtuelle, le système va, à un bas niveau, "mapper" cette page virtuelle sur une section de la mémoire physique, puis l'écrire. Mais l'application elle-même n'a pas à se soucier de ces détails, elle agit simplement comme si elle avait un accès complet à une zone virtuelle de la mémoire.

Dans le cas des applications Java, ce n'est pas l'application elle-même, mais Java qui se voit attribuer cet espace d'adressage, et Java demande simplement un espace d'adressage énorme par défaut - la quantité qu'il demande est calculée par rapport à la taille de la mémoire physique, mais pas parce qu'il a besoin d'être conservateur, mais juste pour des raisons pratiques - une application est probablement ne va pas vouloir une taille de tas suffisante pour mettre totalement à genoux un serveur, il fonctionne donc en supposant qu'il ne le fera pas. Comme je l'ai dit plus haut, cela ne signifie pas que cette quantité est "allouée" ou que le système a dû dépenser beaucoup de ressources à cet effet.

7voto

Pieter B Points 1096

Ce n'est pas votre programme qui utilise cette mémoire, c'est la VM Java qui la réserve, quel que soit le programme chargé.

3voto

Il ne s'agit pas de la quantité de mémoire physique que l'application utilise réellement. La mémoire virtuelle utilisée par tous les processus peut être supérieure de plusieurs ordres de grandeur à la quantité de mémoire vive physique de la machine, sans problème évident.

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