He escrito una biblioteca en C que consume mucha memoria (millones de pequeños bloques). He escrito un programa c que usa esta biblioteca. Y he escrito un programa Java que usa la misma biblioteca. El programa Java es una capa muy delgada alrededor de la biblioteca. Básicamente, solo hay un método nativo que se llama, hace todo el trabajo y regresa horas después. No hay comunicación adicional entre Java y la biblioteca nativa usando la interfaz de invocación java. Tampoco hay un objeto Java que consuma una cantidad notable de memoria.¿Por qué una biblioteca nativa usa 1.5 veces más memoria cuando es utilizada por Java que cuando es usada por un C-Programm bajo Linux?
Así que el programa c y el programa Java son muy similares. Toda la asignación de computación/memoria ocurre dentro de la biblioteca nativa. Todavía. Cuando se ejecuta, el programa c consume 3GB de memoria. ¡Pero el programa Java consume 4.3GB! (Cantidad de VIRT informada por la parte superior)
Comprobé el mapa de memoria del proceso de Java (usando pmap). Las bibliotecas solo usan 40MB. Por lo tanto, las bibliotecas adicionales cargadas por Java no son la causa.
¿Alguien tiene una explicación para este comportamiento?
EDIT: Gracias por las respuestas hasta el momento. Para hacerlo un poco más claro: ¡El código java no hace más que invocar la biblioteca nativa UNA VEZ! El montón de Java es de tamaño estándar (quizás 60 MB) y no se usa (excepto para la clase que contiene el método principal y la otra clase que invoca la biblioteca nativa).
El método de la biblioteca nativa es de larga ejecución y realiza muchos mallocs y libera. La fragmentación es una explicación en la que también pensé. Pero dado que no hay código Java activo, el comportamiento de fragmentación debería ser el mismo para el programa Java y el programa c. Como es diferente, también supongo que las implementaciones malloc utilizadas son diferentes cuando se ejecutan en el programa c o en el programa Java.
Observación interesante. No hubiera esperado este comportamiento. – x4u
fragmentación de montón malloc. Ver http://stackoverflow.com/a/28935176/166062 –
@LariHotari Aunque el motivo de esta pregunta era diferente (ver mi respuesta), también tuvimos problemas con la fragmentación. Lo resolvimos cambiando a implementaciones alternativas como tcmalloc, jemalloc o la implementación malloc de locklessinc. –