Question

J'ai une boucle qui engendre beaucoup de fils. Ces fils contient, entre autres, 2 (massives) objets StringBuilder. Ces fils courent alors et font leur chose.

Cependant, je remarque que, après une certaine quantité de fils, je reçois des accidents étranges. Je sais que cela est à cause de ces StringBuilder, parce que quand je leur capacité initiale réduis, je peux commencer beaucoup plus threads. Maintenant, pour ces StringBuilders, ils créent comme celui-ci dans le constructeur de l'objet thread:

StringBuilder a = new StringBuilder (30000);
StringBuilder b = new StringBuilder (30000);

Le point où il se bloque généralement est d'environ 550 fils de discussion, ce qui résulte en un peu plus de 62MB. Combiné avec le reste du programme de la mémoire utilisée est très probablement 64MB, que je lis quelque part en ligne était la taille de defaulf du pool d'allocation de mémoire JVM. Je ne sais pas si cela est vrai ou non.

Maintenant, est-il quelque chose que je fais mal, en quelque sorte que à cause de la conception, j'allouez de la mémoire dans le mauvais sens? Ou est-ce la seule façon et devrais-je dire la machine virtuelle Java pour augmenter sa pool de mémoire? Ou tout autre chose?

En outre, s'il vous plaît ne me dites pas définir une capacité plus faible, je sais que ces StringBuilders augmentent automatiquement leur capacité en cas de besoin, mais je voudrais avoir une solution à ce problème.

Était-ce utile?

Autres conseils

Si vous stockez beaucoup d'informations dans un StringBuilder, vous allez faire référence à revenir à un moment donné? Sinon, il suffit d'écrire à un autre support (DB, etc fichier). Le programme a une quantité limitée de ressources, il ne peut pas tenir tout l'état d'un système complet à la fois. -Xmx vous donnera plus d'espace pour le stockage dans la mémoire, mais il ne fera pas votre capacité de stockage infinie.

Pensez à utiliser un ThreadPoolExecutor, et définir la taille de la piscine au nombre de processeurs sur votre machine. Création de plus de threads que les processeurs est simplement rallongeant.

ExecutorService service = Executors.newFixedThreadPool(cpuCount))

En outre, vous pouvez réduire l'utilisation de la mémoire en écrivant vos chaînes fichiers au lieu de les garder en mémoire avec StringBuilders.

Supposons 1 Mo par fil. C'est le coût de la RAM de créer chacun, au-delà de la mémoire allouée par son processus.

Comme l'a dit Gregory, donner le jvm, certaines options comme -Xmx.

Pensez aussi à utiliser un ThreadPool ou Exécuteur pour faire en sorte que seule une quantité donnée de fils sont en cours d'exécution simultanément. De cette façon, la quantité de mémoire peut être maintenue limitée sans ralentissement (que votre processeur n'est pas capable d'exécuter 550 threads en même temps de toute façon).

Et quand vous utilisez un Exécuteur ne crée pas les StringBuilders dans le constructeur, mais dans la méthode d'exécution.

Vous pouvez utiliser un FileWriter au texte de sortie à un fichier, puis le tirer en arrière avec un FileReader. De cette façon, vous aurez seulement besoin de stocker le nom de fichier dans la mémoire, plutôt que le contenu de la chaîne.

Pour réduire les sujets que vous pouvez utiliser un ExecutorService, ou simplement utiliser quelques fils qui lisent sur une file d'attente.

Je pense qu'avec un peu bricoler, vous pouvez probablement obtenir votre programme jusqu'à ne pas avoir besoin de mémoire du tout.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top