read - vector push_front c++
Huge std:: vector<std:: vector> no libera toda la memoria en destrucción (1)
Las asignaciones pequeñas (creo que hasta 128 KB de forma predeterminada) se administran mediante un montón en proceso y no se devuelven al SO cuando se desasignan; se devuelven al montón para su reutilización dentro del proceso. Las asignaciones más grandes provienen directamente del sistema operativo (llamando a mmap
) y se devuelven al sistema operativo cuando se desasignan.
En su primer ejemplo, cada vector solo necesita asignar suficiente espacio para una sola int
. Tienes cien millones de asignaciones pequeñas, ninguna de las cuales se devolverá al sistema operativo.
En el segundo ejemplo, a medida que el vector crece, hará muchas asignaciones de varios tamaños. Algunos son más pequeños que el umbral mmap
, estos permanecerán en la memoria del proceso; pero, como solo haces esto con un vector, no será una gran cantidad. Si tuviera que usar resize
o reserve
para asignar toda la memoria para cada vector antes de poblarlo, entonces debería encontrar que toda la memoria se devuelve al sistema operativo.
Esta pregunta ya tiene una respuesta aquí:
Cuando usamos un vector muy grande de vectores, encontramos que parte de la memoria no se libera.
#include <iostream>
#include <vector>
#include <unistd.h>
void foo()
{
std::vector<std::vector<unsigned int> > voxelToPixel;
unsigned int numElem = 1<<27;
voxelToPixel.resize( numElem );
for (unsigned int idx=0; idx < numElem; idx++)
voxelToPixel.at(idx).push_back(idx);
}
int main()
{
foo();
std::cout << "End" << std::endl;
sleep(30);
return 0;
}
Eso deja alrededor de 4 GB de memoria colgando hasta que el proceso termina.
Si cambiamos la línea por
for (unsigned int idx=0; idx < numElem; idx++)
voxelToPixel.at(0).push_back(idx);
la memoria se libera.
Usando gcc-4.8
en una máquina Linux. Hemos utilizado htop
para rastrear el uso de la memoria en una computadora con 100 GB de RAM. Necesitará alrededor de 8 GB de RAM para ejecutar el código. ¿Puedes reproducir el problema? ¿Alguna idea sobre por qué está sucediendo eso?
EDITAR: Hemos visto que eso no sucede en una Mac (con gcc
o clang
). Además, en Linux, la memoria se libera si llamamos a foo
dos veces (pero ocurre nuevamente la tercera vez).