Esta es una pregunta que hemos tenido problemas para entender. Es complicado describirlo usando texto, pero espero que se comprenda la esencia.Tamaño de pila retenido de una cadena en java
Entiendo que el contenido real de una cadena se incluye en una matriz de caracteres interna. En instancias normales, el tamaño de almacenamiento retenido de la cadena incluirá 40 bytes más el tamaño de la matriz de caracteres. Esto se explica here. Al llamar a una subcadena, la matriz de caracteres conserva una referencia a la cadena original y, por lo tanto, el tamaño retenido de la matriz de caracteres podría ser mucho mayor que la cadena misma.
Sin embargo, al perfilar el uso de la memoria con Yourkit o MAT algo extraño parece suceder. La cadena que hace referencia al tamaño retenido de la matriz char no incluye el tamaño retenido de la matriz de caracteres.
Un ejemplo podría ser el siguiente (semi pseudo-código):
String date = "2011-11-33"; (24 bytes)
date.value = char{1172}; (2360 bytes)
tamaño conservado de la cadena se define como 24 bytes, sin incluir el tamaño de retenido de la matriz de caracteres. Esto podría tener sentido si hay muchas referencias a la matriz de caracteres debido a muchas operaciones de subcadenas.
Ahora, cuando esta cadena se incluye en algún tipo de colección, como una matriz o lista, el tamaño retenido de esta matriz incluirá el tamaño retenido de todas las cadenas, incluido el tamaño retenido de la matriz de caracteres.
entonces tenemos una situación como esta:
Array's retained size = 300 bytes
array[0] = String 40 bytes;
array[1] = String 40 bytes;
array[1].value = char[] (220 bytes)
Es, por tanto, tiene que mirar en cada entrada de la matriz a tratar de llegar a donde el tamaño retenido viene.
De nuevo, esto se puede explicar porque la matriz contiene todas las cadenas que mantienen referencias a la misma matriz de caracteres y, por lo tanto, el tamaño retenido de la matriz es correcto.
Ahora llegamos al problema.
Guardo en un objeto separado una referencia a la matriz que mencioné anteriormente, así como una matriz diferente con las mismas cadenas. En ambas matrices, las cadenas se refieren a la misma matriz de caracteres. Esto es esperado, después de todo, estamos hablando de la misma cadena. Sin embargo, el tamaño retenido de este conjunto de caracteres se cuenta para ambas matrices en este nuevo objeto. En otras palabras, el tamaño retenido parece ser el doble. Si elimino la primera matriz, la segunda matriz aún tendrá una referencia a la matriz de caracteres y viceversa. Esto causa una confusión en el sentido de que parece que Java contiene dos referencias separadas para la misma matriz de caracteres. ¿Cómo puede ser esto? ¿Es esto un problema con la memoria de Java o es solo la forma en que los perfiladores muestran información?
Este problema nos causó muchos dolores de cabeza al intentar rastrear el gran uso de memoria en nuestra aplicación.
Nuevamente - Espero que alguien allí pueda entender la pregunta y explicarla.
Gracias por su ayuda
Voy a descargar la evaluación de jprofiler para ver si tiene más sentido. Gracias por tu respuesta. Parece tener más sentido ... – slbruce
Lamentablemente, encontré jprofiler muy difícil de usar. No tengo tiempo para aprender cómo usarlo en todo su potencial, así que simplemente tomaré su palabra :) Gracias por su ayuda – slbruce
Como muestra de su agradecimiento, podría aceptar mi respuesta :-) Y déjame le aseguro que JProfiler no es difícil de usar en absoluto. Para el ejemplo anterior, solo toma una instantánea de montón, selecciona la clase que contiene las matrices y activa la vista de "objetos más grandes". –