Le problème est que, d'une certaine façon, en raison de timings de collecte de place, j'ai des compromis dans ma performance. La question peut être généralisée comme:Garbage collection overload, Java
public void loop(BlockingQueue<Runnable> queue)
{
int j = queue.size();
for(int i =0; i<j;i++)//line2
{
Runnable runnable = queue.take();
runnable.run();//line4
if(Math.random() > 0.9) System.gc();//line5
}
//line7 //will 'runnable = null;' answer the question, logically it looks right
}
maintenant normalement la file d'attente passé comme argument contiendra plus de 40.000 éléments normalement. Et parce que je suis en train d'itérer sur la file d'attente dans une boucle, même si les objets 'run' sont hors de portée, ils ne sont toujours pas disponibles pour garbage Collection car ils sont dans invisible state. Par conséquent, si je n'ai pas la ligne 5, alors il y aura une énorme charge sur le garbage collector quand la méthode sortira de la pile. Imaginez si plusieurs threads accèdent simultanément au menthod.
Mes questions:
- est la ligne 5 nécessaire? Y a-t-il un autre substitut?
- Si je dois avoir la ligne 5, j'ai découvert que la performance était très très mauvaise par rapport à ne pas l'avoir.
En fin de compte garbage collection doit se produire? Je suis incapable de comprendre quand cela devrait arriver.
PS: Javascript est désactivé sur mon ordinateur, donc je ne peux pas commenter les réponses. Je vais éditer le poste ici pour les commentaires:
@amit: J'ai changé le code, je pense que vous avez compris l'essence du problème. Le code est juste un échantillon.
@Tobi: Merci, mais comment va configurer une plus grande taille de tas, résoudre le problème. C'est seulement retarder l'heure de gc. Donc, vous pensez qu'il fonctionnera le mieux sans gc manuel? En outre de http://java.sun.com/docs/books/performance/1st_edition/html/JPAppGC.fm.html, il dit que seulement une fois la méthode est prise de la pile, alors seulement dans ce cas, il serait disponible pour la récupération de place. Et j'ai essayé avec finalize() (en ayant une impression, pas la bonne façon, mais devrait au moins travailler une fois pour 100000 objets), il n'y a absolument pas de gc.
@Paolo: Merci. Ce que j'essaye d'implémenter est un modèle de pipelining, où chaque thread a une file d'attente de meassage, fondamentalement un cadre où n'importe quel fil peut signaler un runnable à l'autre thread (si cela a du travail avec le thread), et l'autre thread exécutera Quand je veux dire, surcharger quand la méthode sort de la pile, ce que je veux dire, c'est que la coltination des ordures finira par arriver, si cela arrive plus tard, alors effacer 40 000 éléments prendra beaucoup de temps.
@ Joachim Sauer: System.gc peut collecter des objets invisibles, c'est juste que le garbage collector ne les collecte pas automatiquement. Mais lorsqu'il est forcé, il fait comme pour: http://java.sun.com/docs/books/performance/1st_edition/html/JPAppGC.fm.html
J'ai changé: line3: run-> runnable, wueue-> queue, rollback si je me trompe, et vous voulez dire en fait les membres de la classe, mais je suppose non – amit
aussi: Je doute que vous vouliez itérer de 'i = 0' à 'queue.size()', note 'queue.size()' change quand vous utilisez 'take()', donc si vous avez 2 éléments dans la file, vous ne 'irez' que sur le premier, car après 'take()' change la taille de 1, et 'i <1 == false'. probablement vous cherchez while (queue.isEmpty() == false) ' – amit
Vous avez dit que vous avez généralisé le problème: pouvez-vous * reproduire * le problème avec ** ce ** code généralisé? Si ce n'est pas le cas, vous pourriez très bien avoir trop généralisé et devrez peut-être nous montrer le vrai code. –