2010-11-11 5 views
0

Nous avons une grande classe avec 68 int, 22 membres doubles, et il y a aussi 4 membres en classe. par exemple java: Comment la mémoire d'un membre de la classe est-elle allouée?

Class A{ 

    public int i1 

    public int i2 

    public int i3 

    .... 

    public Order order1 


    public Order order2 

    ... 

    public double.. 

} 

1: La mémoire de i1, i2, i3 est toujours physiquement?

2: Pour la classe A, stocke-t-il le pointeur sur order1 & order 2, ou stocke-t-il le contenu de la commande 1 & order 2?

Il existe une autre classe B qui a un membre sous la forme d'un tableau de A, il y a 365 A. Donc la mémoire pour B pourrait être très grande. Ma préoccupation est que si la taille de B est trop grande, nous pouvons avoir beaucoup de cache de niveau 2 manquant et dégrader les performances. Nous allons principalement additionner la valeur de i1, et additionner la valeur de i2, et additionner la valeur de i3 etc. par exemple si somme i1 pour tout 365 A, alors le i1 pour tous ces 365A ne restera pas continuellement dans la mémoire. Nous pourrions donc manquer un cache et obtenir de mauvaises performances.

Je pense à l'aide de la classe B, mais retirer la classe A, et déplacer tous les éléments à l'intérieur de A à B, afin que nous puissions

Class B { 

    public array_of_i1 

    public array_of_i2 
.. 

} 

De cette façon, lorsque je calcule la somme de i1 ou i2, alors tous les i1 ou i2 sont assis ensemble, alors peut-être que nous pourrions obtenir une amélioration de la performance?

Comme la classe est énorme, je voudrais chercher vos opinions avant le changement.

Répondre

3

Il est généralement consécutif, mais cela dépend de la machine virtuelle Java que vous utilisez.

Une complication est que l'exécution dans structure de mémoire des objets Java est pas appliquée par la machine virtuelle spécification, ce qui signifie que fournisseurs de machines virtuelles peuvent les mettre en œuvre comme ils s'il vous plaît. La conséquence est que vous pouvez écrire une classe , et les instances de cette classe dans une machine virtuelle peuvent occuper une quantité différente de mémoire que les instances de cette même classe lorsqu'elle est exécutée sur une autre machine virtuelle.

En ce qui concerne la mise en page spécifique,

Pour économiser de la mémoire, le Soleil VM ne fixe pas les attributs de l'objet dans le même ordre dans lequel ils sont déclarés. Au lieu de cela, les attributs sont organisés en mémoire dans l'ordre suivant:

  1. double et désire ardemment
  2. ints et flotteurs
  3. short et caractères
  4. booléens et octets
  5. références

(à partir de http://www.codeinstructions.com/2008/12/java-objects-memory-structure.html)

Il inclut également la gestion des classes héritées.

1

Premièrement, avant de vous lancer dans un travail, avez-vous profilé votre application? Les erreurs de cache causent-elles un goulot d'étranglement?

Quelles sont vos exigences de performance? (Note: 'Aussi vite que possible' isnt une exigence *)

0
  1. Ce serait dépendant de la mise en œuvre.
  2. Oui, il stocke les pointeurs. Les objets résideront ailleurs.
3

Le JLS n'a pas fortement spécifier les dimensions exactes d'objets, donc cela peut varier entre les implémentations de la JVM (si vous pouvez en déduire quelques inférieur limites, à savoir un entier doit être au moins 32 bits). Dans la JVM de Sun, cependant, les entiers prennent 32 bits, les doubles prennent 64 bits et les références d'objet prennent 32 bits (sauf si est exécuté sur une JVM 64 bits et la compression du pointeur est désactivée). Ensuite, l'objet lui-même a un en-tête de 2 mots et la taille de la mémoire globale est alignée sur un multiple de 8 octets. Donc dans l'ensemble, cet objet devrait prendre 8 * ceil((8 + 68 * 4 + 22 * 8 + 4 * 4)/8) = 10448 octets, si je n'ai pas oublié de rendre compte de quelque chose (ce qui est tout à fait possible), et si vous utilisez une machine 32 bits.

Mais - comme indiqué ci-dessus, vous ne devriez pas vraiment compter trop fortement sur ce qu'il est spécifié nulle part, et sera varient entre les implémentations et sur différentes plates-formes. Comme toujours avec les métriques liées aux performances, la clé consiste à écrire du code propre, à mesurer l'impact (dans ce cas, utilisez un profileur pour connaître l'utilisation de la mémoire et le temps d'exécution), puis à optimiser selon les besoins.

Les performances ne sont vraiment importantes que du point de vue macro; s'inquiéter de manquer de cache L2 lors de la conception de votre modèle d'objet est vraiment le mauvais moyen de le faire.

(Et une classe avec 94 champs est certainement pas une conception propre, de sorte que vous avez raison de considérer refactorisation it ...)

0
  1. En général, oui. Mais je ne pense pas que vous vouliez nécessairement en dépendre. Mauvaise langue pour ce genre de choses de bas niveau. Pointeurs, mais je ne sais pas pourquoi c'est important.
  2. Profil avant d'apporter des modifications significatives pour des raisons de performances. Je pense que le second est nettoyeur cependant. Ne préféreriez-vous pas faire une simple boucle de tableau pour votre sommation?

Ou vous pouvez changer la structure d'utiliser une plus petite classe, en gardant les choses qui fonctionne dans une boucle serrée, ensemble, ont tendance à améliorer au cache (IFF qui est votre goulot d'étranglement).

Questions connexes