2010-04-27 2 views
4

Je voudrais poser des questions à propos de surcharge de mémoire en java, J'ai une grande ArrayList (61,770 éléments), et en essayant de calculer la quantité de mémoire prise par chaque élément (en comptant l'objet et son entrée ArrayList), En profilant l'application, j'obtiens qu'après que toutes les données ont été chargées, le tas prend ~ 25Mb. lorsque l'ArrayList a seulement 2 éléments le tas prend ~ 1Mb, donc à peu près:Dépense de mémoire Java

(24 * 1024 * 1024)/61,768 = 407 octets.

cependant, quand je compte les champs de chaque objet, je reçois 148 octets (non compris le ArrayList, et à supposer que int = 4, float = 4, référence = 4), je suis curieux de savoir où a fait tous ces octets supplémentaires viennent de ...

Je peux deviner que puisque les objets que je stocke dans ArrayList implémentent une interface, ils stockent des valeurs supplémentaires, peut-être que la VM stocke un pointeur de fonction de 4 octets pour chaque méthode implémentée? l'interface qu'ils implémentent a 20 fonctions donc 80 octets de plus, totalisant 228 octets, toujours pas près des 400 octets mesurés.

toute aide serait appréciée.


wow, merci pour toutes les bonnes réponses.

@Bolo: merci pour le lien, avec cette classe je mesure ~ 350 octets par objet donc je peux au moins confirmer la source de la grande utilisation de la mémoire.

@Yuval A: merci pour cette présentation, une précieuse source d'information.

@Ukko: point noté.

@Jayan: maintenant NetBeans profiler me donne des erreurs lorsque j'essaie de vider le tas, réessayera plus tard.

+3

Cet article peut vous être utile: http://www.javaworld.com/javaworld/javatips/jw-javatip130.html – Bolo

+0

Si vous démarrez avec une nouvelle ArrayList (61770) à la place, par exemple, d'une nouvelle ArrayList () et laissez-le ensuite redimensionner automatiquement, vous obtiendrez également un surcoût différent. Avez-vous défini la taille correcte avant de vérifier l'utilisation de la mémoire? – extraneon

+0

@flamealpha: 61 770 n'est pas grand :) J'ai HashMap si grand qu'ils mettent la plupart des systèmes à genoux ... C'est pourquoi je les ai remplacés par * TIntIntHashMap * de Trove qui sont juste * * beaucoup plus de mémoire/rapidité efficace :) Hélas, cela ne fonctionne qu'avec les primitives: -/ – SyntaxT3rr0r

Répondre

4

Ces résultats ne sont pas surprenants. La machine virtuelle Java ajoute d'énormes quantités de frais généraux à chaque objet. À peu près le double de la taille attendue pour un seul objet, en raison de l'en-tête de la mémoire JVM, n'est pas rare.

This presentation a une merveilleuse, en profondeur, une explication et une vue d'ensemble de diverses utilisation de la mémoire de structure de données en Java.

+0

désolé de le dire mais ça ne marche pas – Gattsu

1

La mémoire consommée par arraylist est un peu vague. Effectuez un vidage de tas du processus à l'étape appropriée - après que les valeurs ont été entièrement affectées. Ensuite, utilisez des outils comme l'analyseur de mémoire (d'éclipse).

Vous trouverez des tailles de tas peu profondes et conservées.

2

Une ArrayList est généralement plus grande que le nombre d'éléments. Utilisez getCapacity() pour obtenir la taille actuelle du tableau sous-jacent.

2

Un gros problème avec votre approche est l'interaction avec le garbage collector. Il rend fondamentalement tout test comme vous l'avez proposé totalement opaque de l'extérieur.

Comme une expérience de pensée si vous voulez faire cela, vous devez

  1. feu votre machine virtuelle Java et faire un couple de GCS global pour obtenir tous les pourriels sur
  2. Mesurer la taille du tas et la notion de Java combien d'espace libre il a.
  3. Exécutez votre test
  4. GC deux ou trois fois
  5. Refaire les mesures de l'étape # 2

Après tout cela et un peu de mathématiques, vous serez plus proche, mais toujours pas droit. La seule vraie solution consiste à demander la mise en œuvre comme d'autres personnes l'ont mentionné. Ou comprendre à partir de la connaissance de la mise en œuvre.

0

En note, puisque vous savez exactement combien d'objets seront dans votre ArrayList, pourquoi ne pas simplement utiliser un tableau []? Le nombre d'objets va-t-il changer?

+0

c'est juste un exemple de cas, le nombre exact d'éléments à charger n'est pas prédéterminé, mon plus grande préoccupation est la surcharge de mémoire de l'objet vers lequel pointe le tableau. – user326841