C ++: Medición del uso de memoria desde el programa, Windows y Linux [duplicado]

Esta pregunta ya tiene una respuesta aquí:

¿Cómo determinar el consumo de CPU y memoria desde el interior de un proceso? 9 respuestas

Mira, quería medir el uso de memoria de mi programa C ++. Desde el interior del programa, sin perfiladores o visores de procesos, etc.

¿Por qué desde dentro del programa?

Las mediciones se realizarán miles de veces; deben automatizarse; por lo tanto, tener un ojo enTask Manager, toplo que sea, no serviráLas mediciones deben hacerse.durante las corridas de producción—La degradación del rendimiento, que puede ser causada por los perfiladores, no es aceptable ya que los tiempos de ejecución ya no son insignificantes (varias horas para casos de grandes problemas)

Nota. ¿Por qué medir en absoluto? La única razón para medir la memoria usada (según lo informado por el sistema operativo) en lugar de calcular el uso "esperado" de antemano es el hecho de que no puedo directamente, analíticamente "sizeof"Cuánto utiliza mi estructura de datos principal. La estructura misma es

unordered_map<bitset, map<uint16_t, int64_t> >

estos están empaquetados en unvector por todo lo que me importalist en realidad sería suficiente, solo necesito acceder a las estructuras "vecinas"; sin detalles sobre el uso de la memoria, apenas puedo decidir cuál elegir)

vector< unordered_map<bitset, map<uint16_t, int64_t> > >

así que si alguien sabe cómo "dimensionar" la memoria ocupada por dicha estructura, eso también resolvería el problema (aunque probablemente tendría que bifurcar la pregunta o algo así).

Ambiente: Se puede suponer que el programa se ejecuta solo en la máquina dada (junto con el sistema operativo, etc., por supuesto; ya sea una PC o un nodo de supercomputadora); es seguro que es el único programa que requiere grandes cantidades de memoria (digamos> 512 MiB)entorno de experimento computacional. El programa se ejecuta en la PC de mi casa (16GiB RAM; Windows 7 o Linux Mint 18.1) o en el nodo de la supercomputadora de la institución (alrededor de 100GiB RAM, CentOS 7), y el programapuede querer consumir toda esa RAM.Nota que la supercomputadora prohíbe efectivamente el intercambio de discos de los procesos del usuario y que mi PC doméstica tiene un archivo de página más pequeño

Patrón de uso de memoria. Se puede decir que el programasecuencialmente llenar una especie de tabla, cada fila en la que es elvector<...> como se especifica arriba. Digamos que la estructura de datos primarios se llamasupp. Entonces, para cada enterok, allenar supp[k], los datos desupp[k-1] es requerido. Comosupp[k] está lleno se utiliza parainicializar supp[k+1]. Por lo tanto, en cada momento,esta, prevypróximo Las "filas de la tabla" deben ser fácilmente accesibles. Después de llenar la tabla, el programa realiza una búsqueda no rápida, relativamente rápida (en comparación con "inicializar" y llenar la tabla), a través de la cual se obtiene una solución.Nota que la memoria solo se asigna a través deSTL contenedores, nunca explícitamentenew() omalloc() yo mismo.

Preguntas Ilusiones

¿Cuál es la forma adecuada de medir?uso de memoria total (incluido el intercambio a disco) de un procesodesde adentro de su código fuente (uno para Windows, uno para Linux)?Probablemente debería ser otra pregunta, o más bien una buena sesión de búsqueda en Google, pero aún así, ¿cuál es la forma correcta (o sencilla) de controlar explícitamente (por ejemplo, alentar o desalentar) el intercambio en el disco? Un puntero a un libro autorizado sobre el tema sería muy bienvenido. Nuevamente, perdone mi ignorancia, me gustaría un medio para decir algo como "NUNCA intercambiesupp"O" intercambiosupp[10]"; entonces, cuando lo necesito, "cancelarsupp[10]"—Todos del código del programa. Pensé que tendría que resolver serializar las estructuras de datos y almacenarlas explícitamente como un archivo binario, luego invertir la transformación.

En Linux, parecía más fácil capturar los punteros del montón a través de sbrk (0), convertirlos como enteros sin signo de 64 bits y calcular la diferencia después de que se asigna la memoria, y este enfoque produjo resultados plausibles (no fue más riguroso pruebas todavía).

editar 5. Se eliminó la referencia aHeapAlloc discutiendo, irrelevante.

editar 4. solución de Windows Este bit de código informa el conjunto de trabajo que coincide con el del Administrador de tareas; eso es todo lo que quería: probado en Windows 10 x64 (probado por asignaciones comonew uint8_t[1024*1024], o mejor,new uint8_t[1ULL << howMuch], no en mi "producción" todavía). En Linux, lo intentaríagetrusage o algo para obtener el equivalente. El elemento principal esGetProcessMemoryInfo, como lo sugieren @IInspectable y @conio

#include<Windows.h>
#include<Psapi.h>
//get the handle to this process
auto myHandle = GetCurrentProcess();
//to fill in the process' memory usage details
PROCESS_MEMORY_COUNTERS pmc;
//return the usage (bytes), if I may
if (GetProcessMemoryInfo(myHandle, &pmc, sizeof(pmc)))
    return(pmc.WorkingSetSize);
else
    return 0;

editar 5. Se eliminó la referencia aGetProcessWorkingSetSize como irrelevante Gracias @conio.

Respuestas a la pregunta(2)

Su respuesta a la pregunta