Estoy usando una clase interna que es una subclase de HashMap. Tengo un String
como clave y double[]
como valores. Guardo alrededor de 200 dobles por double[]
. Debería usar alrededor de 700 MB para almacenar las claves, los punteros y los dobles. Sin embargo, el análisis de memoria revela que necesito mucho más que eso (un poco más de 2 GB).Serializable, clonable y uso de memoria en Java
Usando TIJmp (herramienta de perfilado) vi que había un char[]
que estaba usando casi la mitad de la memoria total. TIJmp dijo que char[]
provino de Serializable
y Cloneable
. Los valores que contiene van desde una lista de fuentes y rutas predeterminadas a mensajes y caracteres individuales.
¿Cuál es el comportamiento exacto de Serializable
en la JVM? ¿Mantiene una copia "persistente" todo el tiempo, doblando el tamaño de la huella de mi memoria? ¿Cómo puedo escribir copias binarias de un objeto en tiempo de ejecución sin convertir la JVM en una memoria parabólica?
PD: El método donde el consumo de memoria aumenta más es el siguiente. El archivo tiene alrededor de 229,000 líneas y 202 campos por línea.
public void readThetas(String filename) throws Exception
{
long t1 = System.currentTimeMillis();
documents = new HashMapX<String,double[]>(); //Document names to indices.
Scanner s = new Scanner(new File(filename));
int docIndex = 0;
if (s.hasNextLine())
System.out.println(s.nextLine()); // Consume useless first line :)
while(s.hasNextLine())
{
String[] fields = s.nextLine().split("\\s+");
String docName = fields[1];
numTopics = fields.length/2-1;
double[] thetas = new double[numTopics];
for (int i=2;i<numTopics;i=i+2)
thetas[Integer.valueOf(fields[i].trim())] = Double.valueOf(fields[i+1].trim());
documents.put(docName,thetas);
docIndex++;
if (docIndex%10000==0)
System.out.print("*"); //progress bar ;)
}
s.close();
long t2 = System.currentTimeMillis();
System.out.println("\nRead file in "+ (t2-t1) +" ms");
}
Ah !, y HashMapX es una clase interna declarada como esto:
public static class HashMapX< K, V> extends HashMap<K,V> {
public V get(Object key, V altVal) {
if (this.containsKey(key))
return this.get(key);
else
return altVal;
}
}
¿Puede mostrar algunas muestras de código? – axtavt
Por favor, publique las pruebas que muestran que Serializable aumenta la huella de memoria. Si pudieras publicar el código que muestra mucha RAM, tu Map está usando eso también. –
Déjame ver si entiendo tu declaración allí. ¿Estás diciendo que al declarar una clase Serializable el tamaño ocupado por instancias de este es mayor que si fuera transitorio? –