?summaryRprof
говорит:
Если память = "оба" один и тот же список, но с использованием памяти в МБ в дополнение к таймингу.
Итак mem.total
в МБ
С памятью = "оба" сообщается об изменении общего объема памяти (обрезается до нуля) [...]
У вас 8 ГБ ОЗУСвоп + 12 ГБ, но mem.total
заявляет, что вы использовали 50 ГБ?
Поскольку это агрегированная дельта между двумя последующими пробами (снимки использования памяти, сделанные Rprof
через регулярные промежутки времени: Если зондирование выполняется во время выполнения функции f Дельта использования памяти до последнего зондирования добавляется к mem.total
из f).
Дельта использования памяти может быть отрицательной но я никогда не видел отрицательных mem.total
значений, поэтому я предполагаю (!) только положительные значения добавляются к mem.total
.
Это объясняет общее использование 50 ГБ, которое вы видите: Это необъем выделенной памяти в течение одной точки времени, но суммарная дельта памятиполное время выполнения.
Это также объясняет тот факт, что gc
показывает только 3 ГБ как «максимальное использованное (МБ)» : память выделяется и освобождается / освобождается много разтак что вы не столкнетесь с нехваткой памяти, но это будет стоить много времени (перемещение большого количества данных в ОЗУ делает недействительными все кэши и, следовательно, работает медленно) поверх логики вычислений, которую применяет ЦП. ИМХО) также, кажется, скрывает тот факт, что сборщик мусора (gc) запускается в недетерминированные моменты времени для очистки освобожденной памяти.
Поскольку gc запускается ленивым (не-детерминистически) ИМХО было бы несправедливо приписывать отрицательные дельты памяти одной только что проверенной функции.
Я бы интерпретировал mem.total
как mem.total.used.during.runtime
, что, возможно, было бы лучшей меткой для столбца.
profvis
содержит более подробную сводку об использовании памяти (как вы можете видеть на скриншоте в вашем вопросе): он также объединяет отрицательное дельtas (освобожденная память), но документация profvis также предупреждает о недостатках:
Панель кода также показывает распределение и освобождение памяти. Интерпретация этой информации может быть немного хитрой, потому что она не обязательно отражает память, выделенную и отключенную в этой строке кода. Профилировщик выборки записывает информацию о распределении памяти, которое происходит между предыдущей выборкой и текущей. Это означает, что значения выделения / освобождения в этой строке могли действительно иметь место в предыдущей строке кода.
Более подробный ответ потребует больше времени для исследования (у меня нет) - чтобы посмотретьв источник C и R - чтобы понять (воспроизвести) логику агрегирования summaryRprof
на основе файлов данных, созданных Rprof
Rprof
файлов данных (Rprof.out
), выглядят следующим образом:
:376447:6176258:30587312:152:1#2 "test" 1#1 "test2"
Первые четыре числа (разделенные двоеточиями) означают (см. ?summaryRprof
) - R_SmallVallocSize: векторная память [количество сегментов] в маленьких блоках в куче R - R_LargeVallocSize: векторная память [числоячеек] в больших блоках (из malloc) - память в узлах в куче R - количество вызовов внутренней функции duplicate
во временном интервале (используется для дублирования векторов, например, в случае копирования на первое место)-записать семантику аргументов функции)
Строки представляют собой стек вызовов функций.
Только первые два числа имеют значение для вычисления текущей памятииспользование (векторов) в МБ:
TotalBuckets = R_SmallVallocSize + R_LargeVallocSize
mem.used = TotalBuckets * 8 Bytes / 1024 / 1024
# 50 MB in the above `Rprof` probe line:
# (376447 + 6176258) * 8 / 1024 / 1024
Подробнее о Vcells
см. ?Memory
.
Кстати: я хотел попробовать summaryRProf(memory = "stats", diff = F)
, чтобы получить текущую памятьрезюме, но я получаю сообщение об ошибке с 64-битным R3.4.4 в Ubuntu:
Error in tapply(seq_len(1L), list(index = c("1::#File", "\"test2\":1#1", :
arguments must have same length
Можете ли вы воспроизвести это (похоже, что "статистика" не работает)?