Existe este problema en Linux cuando un proceso asigna la misma memoria física a varias direcciones a la vez ("asignación múltiple del montón").
Por ejemplo,Recolector de basura ZGC de JavaHaz esto.
Cuando ocurre el mapeo múltiple del montón, Linux (al menos las versiones que uso) calcula mal (sobreinforma) el tamaño del proceso residente. Esto afecta a la parte superior y a todos los programas que consultan el tamaño de los procesos en el sistema operativo.
En efecto, ya no tengo forma de saber qué tan grande es realmente un proceso.
Esta captura de pantalla es lo que se muestra arriba para un programa Java habilitado para ZGC con <<200 MB de objetos Java. Entonces, en realidad, el proceso ocupa alrededor de 500 MB, no varios GB.
Entonces, para pasar a la pregunta: ¿Alguien conoce una versión (o parche o herramienta) de Linux que pueda informar correctamente los tamaños de proceso en este caso?
Editar:Ahora hice mi propia pequeña herramientaespecíficamente para el caso de uso ZGC.
Respuesta1
Podría preguntarle al kernel cómo usa el proceso la memoria ( /proc/PID/smaps
) y luego hacer los cálculos basándose en la memoria compartida y privada informada. La memoria compartida sólo debe contarse una vez.
A continuación se muestra un código que analiza smaps y resume los distintos tipos de uso de memoria para obtener una lista de pids. La memoria de tamaño de conjunto único (uss) es la memoria privada del proceso y podría dar una mejor idea de cuánta memoria utiliza realmente el proceso. En última instancia, se convierte en una cuestión de cómo le gustaría incluir la memoria compartida en la ecuación.
rss = '.+?Rss:\s+(\d+)' pss = '.+?Pss:\s+(\d+)' shared_clean = '.+?Shared_Clean:\s+(\d+)' shared_dirty = '.+?Shared_Dirty:\s+(\d+)' priv_clean = '.+?Private_Clean:\s+(\d+)' priv_dirty = '.+?Private_Dirty:\s+(\d+)' MEM_REGEXP = /#{rss}#{pss}#{shared_clean}#{shared_dirty}#{priv_clean}#{priv_dirty}/m def self.get_memory_map( pids) memory_map = {} #memory_map[ :pids_searched] = pids memory_map[ :pids_found] = {} memory_map[ :rss] = 0 memory_map[ :pss] = 0 memory_map[ :shared_clean] = 0 memory_map[ :shared_dirty] = 0 memory_map[ :rss_shared] = 0 memory_map[ :priv_clean] = 0 memory_map[ :priv_dirty] = 0 memory_map[ :uss] = 0 pids.each do |pid| begin # We don't want to see any "/proc/9723: No such file or directory" messages in stderr lines = nil Util.silently { lines = File.read( "/proc/#{pid}/smaps") } rescue lines = nil end if lines lines.scan(MEM_REGEXP) do |rss,pss,shared_clean,shared_dirty,priv_clean,priv_dirty| memory_map[ :pids_found][pid] = true memory_map[ :rss] += rss.to_i memory_map[ :pss] += pss.to_i memory_map[ :shared_clean] += shared_clean.to_i memory_map[ :shared_dirty] += shared_dirty.to_i memory_map[ :rss_shared] += shared_clean.to_i + shared_dirty.to_i memory_map[ :priv_clean] += priv_clean.to_i memory_map[ :priv_dirty] += priv_dirty.to_i memory_map[ :uss] += priv_clean.to_i + priv_dirty.to_i end end end memory_map[ :pids_found] = memory_map[ :pids_found].keys return memory_map end