2010-06-01 5 views
2

Mon application alloue une tonne d'objets (> 1mln par seconde, la plupart des objets sont des tableaux d'octets de taille ~ 80-100 et des chaînes de même taille) et je pense que cela pourrait être la source de ses mauvaises performances.La vitesse d'allocation dépend-elle du garbage collector utilisé?

L'ensemble de travail de l'application ne contient que des dizaines de mégaoctets. Le profil de l'application montre que le temps de GC est négligeable.

Cependant, je pense que peut-être la procédure d'attribution dépend du GC est utilisé, et certains paramètres peuvent rendre l'allocation plus rapide ou peut-être faire une influence positive sur le taux de succès de cache, etc.

Est-ce donc? Ou est-ce que la performance de l'allocation est indépendante des paramètres du GC sous l'hypothèse que la récupération de place elle-même prend peu de temps?

+0

Qu'est-ce qu'un "mln"? –

+0

1 mln = 1 million – jkff

+0

sont les objets que vous attribuez de longue date ou sont-ils hors de portée dès qu'ils sont créés? – Justin

Répondre

2

Bien sûr, vos performances dépendent de l'allocateur utilisé. Mais vous avez profilé GC et vu que ce n'est pas vraiment un problème. De plus, l'une des forces du GC est l'allocation rapide au détriment d'une collecte plus lente.

Je pense que vous rencontrez des problèmes avec la fragmentation qui en résulte qui rend le modèle d'accès à la mémoire problématique pour le CPU, car il peut avoir besoin d'invalider son cache trop souvent. La plupart des algorithmes GC ne récupèrent pas l'espace de manière optimale.

Étant donné que votre jeu de travail est limité et prévisible, vous pouvez utiliser un pool d'objets préalablement affecté. Vous pouvez également utiliser le comptage des références pour éviter une grande partie de la gestion manuelle de la mémoire. Techniquement, c'est toujours GC mais pas dans le sens commun du GC.

Cependant, je ne pense pas que la performance soit affectée par la façon dont vous gérez la mémoire, mais comment vous l'utilisez réellement pour y accéder. Très probablement votre profileur a la réponse définitive.

+1

++ Pour le concept "piscine". D'un autre côté, la référence compte? Si vous avez des bugs dans le décompte des références, ils sont très difficiles à trouver. –

+0

Mike: Il n'est pas si difficile d'implémenter le comptage des références dans ce cas. Les objets de pool ne contiennent pas de références elles-mêmes. Et je n'ai pas vu le tag java. – artificialidiot

+0

Malheureusement, mon profileur me donne la merde absolue comme réponse, et j'ai déjà posé une question à ce sujet sur SO. Je sais une chose ou deux sur le profilage, mais dans ce cas, j'ai échoué, je vais essayer l'artillerie lourde comme VTune ... – jkff

1

L'allocation d'objets présente deux aspects distincts. Le premier est de trouver une zone de mémoire appropriée - avec les collecteurs garbarge générationnels d'aujourd'hui, cela est généralement très rapide (de l'ordre de quelques dixièmes de cycles de machine).

La seconde est l'initialisation des objets que vous allouez. Puisque tout ce que vous allouez en Java est initialisé, le coût d'initialisation peut facilement surpasser le coût de l'allocation (à l'exception des objets les plus simples et les plus petits). Il y a plus. Puisque l'initialisation nécessite d'écrire toute la zone mémoire occupée par le nouvel objet (si vous allouez un "nouvel octet [1 < < 20]", par exemple, tout le mégaoctet doit être défini sur zéros), cela entraîne généralement cette mémoire dans les cpu. cache, en expulsant d'autres lignes de cache plus anciennes (qui peuvent appartenir ou non à votre jeu de travail "chaud" actuel).

Si vous effectuez relativement peu de traitement sur chacune de vos baies, ces effets peuvent affecter gravement les performances de votre code. Cela peut être partiellement évité en réutilisant les mêmes tableaux encore et encore, mais cela rend généralement la logique du programme plus complexe. Il est également souvent difficile de déterminer si le cache est vraiment le coupable. Il est impossible de dire à partir de quelle petite information est donnée dans votre question.

0

Votre machine virtuelle essaie-t-elle de regrouper des chaînes? J'avais entendu une fois, que la VM d'IBM faisait quelque chose comme l'internement de chaîne mais dynamiquement (aucune idée si c'est vrai) peut-être votre VM essaie de faire un travail supplémentaire pour construire une structure de données interne de String.

Est-ce que vous faites quelque chose comme par hasard? Vous pouvez essayer de ne pas allouer les objets String, et à la place allouer un objet aléatoire qui a une référence à l'octet [] (pour comparaison).

+0

Oui, je fais quelque chose comme le code que vous avez montré. Mais j'ai besoin des cordes pour diverses raisons. – jkff

Questions connexes