Evitar un “error de falta de memoria” en Java (Eclipse), cuando se utiliza la estructura de datos de gran tamaño?

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

Pregunta

OK, así que estoy escribiendo un programa que, lamentablemente, tiene que utilizar una enorme estructura de datos para completar su trabajo, pero sin poder realizarse con un "error de falta de memoria" durante su inicialización. Si bien entiendo del todo lo que eso significa y por qué es un problema, tengo problemas para su superación, ya que mi programa necesita utilizar esta estructura grande y no sé de ninguna otra manera para almacenarlo.

El programa de primeros índices de un gran corpus de archivos de texto que proporciono. Esto funciona bien.

A continuación, utiliza este índice para inicializar una gran matriz 2D. Esta matriz tendrá entradas N², donde "n" es el número de palabras únicas en el corpus de texto. Para el relativamente pequeño trozo estoy probando o n (alrededor de 60 archivos) que necesita para hacer aproximadamente 30,000x30,000 entradas. Esto probablemente será más grande una vez que corro en mi corpus total pretendido también.

Es consistentemente falla cada vez, después de que los índices, mientras se inicializa la estructura de datos (para ser trabajado en adelante).

Las cosas que he hecho son:

  • renovar mi código para utilizar un int[] primitiva en lugar de un TreeMap
  • eliminar estructuras redundantes, etc ...
  • También, he ejecutar el programa with-Xmx2g a un máximo de mi memoria asignada

Estoy bastante seguro de que esto no va a ser una simple línea de código de solución, pero es más probable que va a requerir un nuevo enfoque. Busco lo que el enfoque es, alguna idea?

Gracias, B.

¿Fue útil?

Solución

Parece que (hacer algunas suposiciones acerca de lo que usted está utilizando su matriz para) la mayor parte de las entradas será 0. Si es así, es posible considerar el uso de un representación matriz dispersa .

Si realmente Tienes que muchas entradas (su matriz actual está en algún lugar más de 3 gigabytes ya , aun suponiendo que no hay gastos generales), entonces usted tendrá que usar algún tipo de almacenamiento en disco, o un sistema / descarga perezoso carga.

Otros consejos

Hay varias causas de los problemas de memoria.

En primer lugar, el caso más simple es que simplemente necesita más del montón. Estás usando 512M almacenamiento dinámico máximo cuando el programa podría funcionar correctamente con 2G. Aumento es con -Xmx2048m como una opción de JVM y ya está bien. También tenga en cuenta que las máquinas virtuales de 64 bits utilizará hasta el doble de memoria de 32 bits máquinas virtuales en función de la distribución de los datos.

Si su problema no es tan simple continuación se puede ver en la optimización. Sustitución de objetos a partir de primitivas y así sucesivamente. Esto podría ser una opción. Yo no puedo decir en base a lo que has enviado.

En última instancia, sin embargo se llega a un cruce de caminos donde se tiene que hacer una elección entre Virtulization y partición .

La virtualización en este contexto significa simplemente alguna forma de pretender que hay más memoria de la que existe. sistemas operativos utilizan esto con espacios de direcciones virtuales y el uso de espacio en disco duro como memoria adicional. Esto podría significar sólo mantener algunos de la estructura de datos en la memoria a la vez y que persiste el resto a un almacenamiento secundario (por ejemplo, archivo o base de datos).

Partición se reparte sus datos a través de múltiples servidores (ya sea real o virtual). Por ejemplo, si estuviera perdiendo de vista operaciones de bolsa en el NASDAQ se puede poner códigos de poblaciones que empiezan por "A" en server1, "B" en la servidor2, etc. Es necesario encontrar un enfoque razonable para rebanar los datos de tal manera que se reduce o eliminar la necesidad de una comunicación cruzada porque esa comunicación cruzada es lo que limita su capacidad de ampliación.

caso tan sencillo, si lo que se está almacenando es 30K y 30K palabras x 30K combinaciones de palabras que podría dividirla en cuatro servidor:

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

Eso es sólo una idea. Una vez más es omment toc dura sin conocer detalles.

Este es un problema común se trata de grandes conjuntos de datos. Puede optimizar tanto como desee, pero el recuerdo nunca será suficiente (probablemente), y tan pronto como el conjunto de datos crece un poco más todavía se fuman. La solución más escalable es simplemente para mantener menos en la memoria, el trabajo en trozos, y persistir la estructura en el disco (base de datos / archivo).

Si usted no necesita un total de 32 bits (tamaño del número entero) para cada valor en su matriz 2D, tal vez un tipo más pequeño, como un byte que hacer el truco? También usted debe darle tanto espacio como sea posible montón - 2 GB es todavía relativamente pequeño para un sistema moderno. RAM es barato, especialmente si esperas estar haciendo una gran cantidad de procesamiento en memoria.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top