Éviter une « erreur de dépassement de mémoire » en Java (Eclipse), lors de l'utilisation à grande structure de données?

StackOverflow https://stackoverflow.com/questions/2459972

Question

OK, donc je suis en train d'écrire un programme qui doit malheureusement utiliser une énorme structure de données pour achever ses travaux, mais il ne parvient pas à une « erreur de dépassement de mémoire » lors de son initialisation. Même si je comprends tout à fait ce que cela signifie et pourquoi il est un problème, je ne parviens pas à le surmonter, étant donné que mon programme a besoin d'utiliser cette grande structure et je ne sais pas d'autre moyen de le stocker.

Le premier index programme un grand corpus de fichiers texte que je propose. Cela fonctionne très bien.

Ensuite, il utilise cet indice pour initialiser un grand tableau 2D. Ce tableau aura des entrées n², où « n » est le nombre de mots uniques dans le corpus de textes. Pour le morceau relativement petit, je suis le tester o n (environ 60 fichiers), il doit faire environ 30,000x30,000 entrées. Ce sera probablement plus une fois que je cours sur mon corpus complet prévu aussi.

Il échoue constamment à chaque fois, après l'index, alors qu'il initialise la structure de données (à travailler sur la suite).

Ce que j'ai fait comprennent:

  • relooker mon code pour utiliser une int[] primitive au lieu d'un TreeMap
  • éliminer les structures redondantes, etc ...
  • Aussi, j'ai couru le programme with-Xmx2g max ma mémoire allouée

Je suis assez confiant cela ne va pas être une simple ligne de solution de code, mais est le plus susceptible d'exiger une approche très nouvelle. Je cherche ce que cette approche est, des idées?

Merci, B.

Était-ce utile?

La solution

On dirait (faire quelques hypothèses sur ce que vous utilisez votre tableau pour) la plupart des entrées sera 0. Si oui, vous pouvez envisager d'utiliser un matrice de représentation clairsemée.

Si vous avez vraiment Vous que de nombreuses entrées (votre tableau actuel est quelque part

Autres conseils

Il y a plusieurs causes de problèmes de mémoire.

Tout d'abord, le cas le plus simple est que vous devez tout simplement plus tas. Vous utilisez tas 512M maximum lorsque votre programme pourrait fonctionner correctement avec 2G. L'augmentation est avec -Xmx2048m comme une option JVM et vous êtes bien. Il faut aussi savoir que 64 machines virtuelles bits utilisera jusqu'à deux fois la mémoire de 32 machines virtuelles bits en fonction de la composition de ces données.

Si votre problème n'est pas aussi simple que cela, alors vous pouvez regarder l'optimisation. Remplacement des objets avec des primitives et ainsi de suite. Cela pourrait être une option. Je ne peux pas vraiment dire sur ce que vous avez posté.

En fin de compte mais vous arrivez à un carrefour où vous devez faire un choix entre virtualisation et partage .

Virtualisation dans ce contexte signifie simplement une certaine forme de faire semblant il y a plus de mémoire qu'il n'y a. Les systèmes d'exploitation utilisent ce avec des espaces d'adresse virtuelle et l'utilisation de l'espace disque dur comme mémoire supplémentaire. Cela pourrait signifier que garder une partie de la structure de données en mémoire à la fois et le reste persistant au stockage secondaire (fichier ou base de données par exemple).

Cloisonnement est le fractionnement de vos données sur plusieurs serveurs (réels ou virtuels). Par exemple, si vous le suivi des transactions boursières sur le NASDAQ, vous pouvez mettre les codes de stock commençant par « A » sur server1, « B » sur server2, etc. Vous devez trouver une approche raisonnable de couper vos données telles que vous réduisez ou d'éliminer la nécessité d'une communication croisée parce que la communication croisée est ce qui limite votre évolutivité.

Si simple cas, si ce que vous stockez est 30K mots et 30K x 30K combinaisons de mots vous pouvez le diviser en quatre serveurs:

  • A-M-M x A
  • A-M x N-Z
  • N-Z x A-M
  • N-Z-Z x N

C'est juste une idée. Encore une fois, il est difficile omment toc sans connaître les détails.

Ceci est un problème commun traitant de grands ensembles de données. Vous pouvez optimiser autant que vous voulez, mais la mémoire ne sera jamais assez (probablement), et dès que l'ensemble de données se développe un peu plus vous fumais encore. La solution la plus évolutive est simplement de garder moins en mémoire, le travail sur les morceaux, et persister la structure sur le disque (base de données / fichier).

Si vous n'avez pas besoin d'un 32 bits complet (taille de nombre entier) pour chaque valeur dans votre tableau 2D, peut-être un type plus petit, comme un octet ferait l'affaire? Aussi, vous devriez lui donner autant d'espace de tas que possible - 2 Go est encore relativement petit pour un système moderne. RAM est pas cher, surtout si vous vous attendez à faire beaucoup de traitement en mémoire.

scroll top