Question

Comment optimiser l'utilisation de la taille du tas d'une application qui a beaucoup (millions) d'objets de longue durée? (Grand cache, chargement beaucoup d'enregistrements à partir d'un db)

  • Utilisez le bon type de données
    • Évitez java.lang.String pour représenter d'autres types de données
  • Évitez les objets dupliqués
    • Utilisez énumérations si les valeurs sont connues à l'avance
    • Utilisez pools d'objets
    • String.intern () (bonne idée?)
  • Charger / ne conserver que les objets dont vous avez besoin

Je suis à la recherche de la programmation générale ou Java des réponses spécifiques. Pas de commutateur de compilateur funky.

Edit:

Optimiser la représentation de la mémoire d'un POJO qui peut apparaître des millions de fois dans le tas.

Les cas d'utilisation

  • Charger un énorme fichier csv en mémoire (converti en POJO)
  • Utilisez hiberner pour récupérer millions d'enregistrements d'une base de données

Reprise des réponses:

  • Utiliser modèle poids mouche
  • Copie sur écriture
  • Au lieu d'objets de chargement 10M avec 3 propriétés, est-il plus efficace d'avoir 3 tableaux (ou une autre structure de données) de taille 10M? (Peut-être une douleur pour manipuler des données, mais si vous êtes vraiment à court de mémoire ...)
Était-ce utile?

La solution

Vous ne dites pas ce genre d'objets que vous cherchez à stocker, il est donc un peu difficile d'offrir des conseils détaillés. Toutefois, certains (non exclusif) approches, sans ordre particulier, sont:

  • Utilisez un mouches où possible.
  • Mise en cache sur le disque. Il y a de nombreuses solutions de cache Java.
  • Il y a un débat quant à savoir si String.intern est une bonne idée. Voir pour une nouvelle question. String.intern (), et la quantité de débat sur sa pertinence.
  • Exploitez href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/ref/SoftReference.html" doux ou faible références à stocker des données que vous pouvez recréer / recharger sur demande. Voir pour savoir comment utiliser doux références avec des techniques de mise en cache.

En savoir davantage sur les entrailles et la vie des objets que vous stockez entraînerait une réponse plus détaillée.

Autres conseils

Je vous suggère d'utiliser un profileur de mémoire, voir où la mémoire est consommée et d'optimiser cela. Sans informations quantitatives que vous pourriez finir par changer chose qui soit ont aucun effet ou fait qu'empirer les choses.

Vous pouvez envisager de modifier la représentation de vos données, en particulier si vos objets sont petites. Par exemple, vous pouvez représenter une table de données comme une série de colonnes avec des tableaux d'objets pour chaque colonne, au lieu d'un objet par ligne. Cela peut économiser une quantité importante des frais généraux pour chaque objet si vous n'avez pas besoin de représenter une ligne individuelle. par exemple. une table avec des colonnes et 12 rangées 10.000.000 12 pourrait utiliser des objets (un par colonne) au lieu de 10 millions (une par ligne)

Assurer une bonne normalisation de votre modèle d'objet, ne pas dupliquer les valeurs.

Ahem, et, si elle est seulement des millions d'objets que je pense que je vais juste pour un 64 bits décent VM et beaucoup de RAM;)

Normal « profileurs » ne vous aidera pas beaucoup, parce que vous avez besoin d'un aperçu de tous vos objets « live ». Vous avez besoin d'un analyseur de vidage de tas. Je recommande le Eclipse analyseur mémoire .

Vérifier les objets dupliqués, en commençant par des chaînes. Vérifiez si vous pouvez appliquer des modèles comme embarqués, copy-on-write, l'initialisation paresseuse (Google sera votre ami).

Jetez un oeil à cette présentation liée ici. Il expose l'utilisation de la mémoire de l'objet java commun et primitives et vous aide à comprendre où toute la mémoire supplémentaire va.

Java efficaces Mémoire du bâtiment Applications: Pratiques et défis

Vous pouvez simplement stocker moins d'objets dans la mémoire. :) Utilisez un cache qui se répand sur le disque ou utiliser Terracotta pour regrouper votre tas (qui est virtuel) permettant les parties non utilisées soient vidées de la mémoire et de façon transparente en arrière dans faillées.

Je veux ajouter quelque chose au point Peter alredy fait (ne peut pas commenter sa réponse :() il est toujours préférable d'utiliser un profileur de mémoire (cocher

Si vous avez des millions de Flotteurs etc. Entiers et puis voir si vos algorithmes permettent de représenter les données dans des tableaux de primitives. Cela signifie moins de références et le coût du CPU de chaque collecte des ordures.

Une fantaisie un: garder la plupart des données compressées dans la RAM. développer uniquement le jeu de travail actuel. Si vos données a une bonne localité qui peut fonctionner très bien.

Utiliser de meilleures structures de données. Les collections standard en java sont plutôt gourmandes en mémoire.

[ce qui est une meilleure structure de données]

  • Si vous jetez un oeil à la source pour les collections, vous verrez que si vous vous restreignez dans la façon dont vous accédez à la collection, vous pouvez économiser de l'espace par élément.
  • La façon dont la collection est de plus en plus gérer pas bon pour les grandes collections. copie trop. Pour les grandes collections, vous avez besoin d'un algorithme basé sur des blocs, comme btree.

Passez un peu de temps à se familiariser avec et à régler les options de ligne de commande VM , en particulier celles relatives à la collecte des ordures. Bien que cela ne changera pas la mémoire utilisée par vos objets, il peut avoir un impact sur les performances avec les applications gourmandes en mémoire sur des machines avec beaucoup de RAM.

  1. valeur Assign null à tous les variables qui sont no longer utilisés. Ainsi make it available for Garbage collection.
  2. De-reference the collections une fois l'utilisation terminée, sinon GC ne sera pas balayer ceux-ci.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top