J'ai un projet que j'écris (en Java) pour une classe où le prof dit que nous ne sommes pas autorisés à utiliser plus de 200m Je limite la mémoire de la pile à 50m (juste pour être absolument sûr) avec -Xmx50m mais selon top , il utilise toujours 300m
J'ai essayé de lancer Eclipse Memory Analyzer et il ne rapporte que 26m
Est-ce que tout cela peut être de la mémoire sur la pile?, Je suis sûr que je ne vais jamais plus loin qu'environ 300 appels de méthode en profondeur (oui, c'est une recherche DFS récursive), donc cela devrait signifier que chaque trame de pile utilise presque un mégaoctet qui semble difficile à croire.
Le programme est monothread. Quelqu'un connaît-il d'autres endroits où je pourrais réduire l'utilisation de la mémoire? De plus, comment puis-je vérifier/limiter la quantité de mémoire utilisée par la pile?
MISE À JOUR: J'utilise maintenant les options JVM suivantes sans effet (toujours environ 300m selon le haut): -Xss104k -Xms40m -Xmx40m -XX:MaxPermSize=1k
Une autre MISE À JOUR: En fait, si je le laisse courir un peu plus longtemps (avec toutes ces options) environ la moitié du temps, il tombe soudainement à 150 m après 4 ou 5 secondes (l'autre moitié, il ne baisse pas). Ce qui rend cela vraiment étrange, c'est que mon programme n'a pas de stochastique (et comme je l'ai dit, il est simple), il n'y a donc aucune raison pour qu'il se comporte différemment sur différentes exécutions
Cela pourrait-il avoir quelque chose à voir avec la machine virtuelle Java que j'utilise?
Java version "1.6.0_27"
OpenJDK Runtime Environment (IcedTea6 1.12.3) (6b27-1.12.3-0ubuntu1~10.04)
OpenJDK 64-Bit Server VM (build 20.0-b12, mixed mode)
Selon Java -h, la JVM par défaut est -server. J'ai essayé d'ajouter -cacao et maintenant (avec toutes les autres options) c'est seulement 59m. Donc je suppose que cela résout mon problème. expliquer pourquoi cela était nécessaire? De plus, y a-t-il des inconvénients que je devrais connaître?
Une dernière mise à jour: cacao est vraiment très lent par rapport au serveur. C'est une terrible option
La commande supérieure reflète la quantité totale de mémoire utilisée par l'application Java. Cela inclut entre autres:
Max memory = [-Xmx] + [-XX:MaxPermSize] + number_of_threads * [-Xss]
ici la mémoire de tas max comme -Xmx, la mémoire de tas min comme -Xms, la mémoire de pile comme -Xss et -XX maxPermSize
L'exemple suivant illustre cette situation. J'ai lancé mon Tomcat avec les paramètres de démarrage suivants:
-Xmx168m -Xms168m -XX:PermSize=32m -XX:MaxPermSize=32m -Xss1m
Avec -Xmx
vous configurez la taille du tas. Pour configurer la taille de la pile, utilisez -Xss
paramètre. La somme de ces deux paramètres devrait être approximativement ce que vous voulez:
-Xmx150m -Xss50m
par exemple.
En outre, il existe également -XX:MaxPermSize
paramètre qui contrôle. Ce paramètre pour -client
a une valeur par défaut de 32 Mo et pour -server
64 Mo. Selon votre configuration, calculez-le également. L'espace PermGen est:
La génération permanente est utilisée pour refléter le VM lui-même, comme les objets de classe et les objets de méthode.
Donc, fondamentalement, il stocke les données internes de la JVM, comme les définitions de classes et les chaînes internes.
À la fin, je dois dire qu'il y a une partie que vous ne pouvez pas contrôler, c'est la mémoire utilisée par le processus natif Java. Java est un programme, juste comme les autres, il utilise donc également la mémoire. Si vous regardez l'utilisation de la mémoire dans le Gestionnaire des tâches, vous verrez cette mémoire ainsi que la consommation de mémoire de votre programme.
Il est important de noter que la "mémoire totale utilisée" (RSS dans le pays Linux) inclut le tas JDK (+ autres zones JDK) ainsi que toute "mémoire native" allouée.
Par exemple, ces personnes ont constaté que l'allocation d'un trop grand nombre de jaxbcontexts (qui ont associé de la mémoire native) entre les GC pourrait lui faire utiliser beaucoup de RAM supplémentaire. Un autre courant est apparemment ZipInflater si vous n'appelez pas à proximité (ou GZipStream, etc.)
http://sleeplessinslc.blogspot.com/2014/08/jvm-native-memory-leak.html
Sa solution de contournement/correction finale consistait soit à GC "plus souvent" (en utilisant GC1 garbage collector, soit en spécifiant un plus petit [ironiquement] paramètre -Xmx) ou en mettant en cache les objets JaxBContext (car ils n'ont pas de méthode close, vous ne pouvez donc pas contrôler la fuite).
Notez également que parfois vous pouvez trouver des coupables de mémoire en examinant simplement jstack: http://javaeesupportpatterns.blogspot.com/2011/09/jaxbcontext-performance-problem-case.html
Il est également parfois possible de "manquer" la fermeture par exemple de GZipStreams accidentellement http://kohsuke.org/2011/11/03/quiz-time-memory-leak-in-Java
Avez-vous essayé d'utiliser JVisualVM?
http://docs.Oracle.com/javase/6/docs/technotes/tools/share/jvisualvm.html
J'ai souvent trouvé que cela m'aide à retrouver ces informations. Il vous montrera la quantité de chaque type de mémoire utilisée, vous permettant même de percer et de découvrir quoi.