linux - tengo - Cómo devolver la memoria del proceso al sistema operativo
ver memoria ram linux terminal (5)
Creo que la única manera confiable y portátil de hacerlo es generar un nuevo proceso para manejar su solicitud. Al salir del proceso, el sistema operativo recolectará toda la memoria asociada.
Desafortunadamente, usted tiene las ineficiencias relacionadas con el engendramiento de este proceso y la comunicación entre procesos (me doy cuenta de que está procesando mucho; no sé si esto implica que su comunicación entre procesos tiene requisitos de datos considerables). Sin embargo, obtendrá el comportamiento de memoria que necesita. Tenga en cuenta que el sistema operativo no debe duplicar la memoria consumida por la JVM real, siempre que genere una imagen binaria JVM idéntica .
Tengo un problema con la administración de memoria en varios sistemas operativos.
Mi programa es un servidor que procesa algo que podría tomar algunos GB de memoria. Después de eso, libera la mayor parte de la memoria mientras espera unas pocas horas hasta que llega otra solicitud.
En AIX y Solaris, observo el siguiente comportamiento:
Cuando libero la memoria, la memoria no vuelve al sistema operativo. La cantidad de memoria virtual utilizada por un proceso siempre aumenta, nunca disminuye. Lo mismo es cierto para la memoria física, hasta su límite. Por lo tanto, parece que usamos toda esta memoria en modo de suspensión también.
¿Cuándo esta memoria puede devolverse al sistema operativo? ¿Cómo puedo hacerlo?
Linux es diferente: parece que devuelve memoria algunas veces, pero no puedo entender cuándo y cómo. Tengo, por ejemplo, un escenario en el que el proceso antes de una solicitud era de 100 MB, luego de 700 MB en el pico, y después de liberar todo eso había bajado a 600 MB. No lo entiendo: si Linux devuelve memoria al SO, ¿por qué no todo?
Deberías ver cómo funciona la paginación. No puede devolver la memoria si es menor que getpagesize ().
La biblioteca glibc (que normalmente se usa como la biblioteca C estándar en Linux) puede asignar memoria de dos maneras: con sbrk () o con mmap (). Utilizará mmap () para asignaciones lo suficientemente grandes.
La memoria asignada con sbrk () no puede abandonarse fácilmente (solo en casos especiales, y hasta donde sé, glibc ni siquiera lo intenta). La memoria asignada con mmap () se puede devolver usando munmap ().
Si depende de poder devolver la memoria al sistema operativo, puede usar mmap () directamente en lugar de malloc (); pero esto se volverá ineficiente si asigna muchos bloques pequeños. Es posible que deba implementar su propio asignador de grupo sobre mmap ().
La mayoría de las veces, la memoria no se devolverá al sistema hasta que finalice el proceso. Según el sistema operativo y la biblioteca de tiempo de ejecución, es posible que se devuelva la memoria al sistema, pero no conozco ninguna forma confiable de garantizar que esto ocurra.
Si el procesamiento requiere unos pocos GB de memoria, pida a su servidor que espere la solicitud y luego genere un nuevo proceso para procesar los datos: puede comunicarse con su servidor utilizando pipes. Cuando finaliza el procesamiento, devuelve el resultado y finaliza el proceso generado.
la forma en que se asigna la memoria (y tal vez devuelta al SO) está en la libc, supongo. El paquete de lenguaje de programación / biblioteca que está utilizando podría ser una razón para esto.
Supongo que glibc devolverá la memoria no fragmentada en la parte superior del montón. Su proceso puede asignar 10MB de datos que usará todo el tiempo. Después de eso, se asignarán 500 MB de datos que se utilizan en el procesamiento. Después de eso, se asigna un pequeño fragmento de datos que se conserva incluso después del procesamiento (podría ser el resultado del procesamiento). Después de eso, se asignan otros 500 MB. El diseño de la memoria es:
| 10MB usado | 500 MB de procesamiento | 1MB resultado | 500MB de procesamiento | = 1011 MB en total
Cuando se liberan los 1000MB, el diseño de la memoria es
| 10MB usado | 500MB liberado | 1MB resultado | 500 MB liberado | glibc ahora puede devolver la memoria al final ... | 10MB usado | 500MB liberado | 1MB resultado | = 511 MB "en uso" también solo se usan 11MB de eso.
Supongo que es lo que sucede, tendrás que investigar más (se me ocurren grupos de memoria separados) para asegurar que toda la memoria se libere.