Как избежать быстрого увеличения памяти во время уборки gc?
У меня есть приложение, созданное для восстановления. У меня нет утечек памяти, однако у меня большой рост памяти во время удаления gc, затем идет тяжелая маркировка gc и очистка памяти.
Это влияет на производительность моего приложения.
[2268] 266859 ms: Scavenge 61.5 (119.5) -> 46.0 (119.5) MB, 2.2 ms [allocation failure].
[2268] 267084 ms: Scavenge 63.7 (119.5) -> 48.3 (119.5) MB, 6.2 ms [allocation failure].
[2268] 267289 ms: Scavenge 66.0 (119.5) -> 50.6 (119.5) MB, 2.6 ms [allocation failure].
[2268] 267504 ms: Scavenge 68.3 (119.5) -> 52.8 (119.5) MB, 2.4 ms [allocation failure].
[2268] 267700 ms: Scavenge 70.5 (119.5) -> 55.1 (119.5) MB, 2.7 ms [allocation failure].
....
[2268] 275913 ms: Scavenge 154.2 (183.5) -> 138.8 (183.5) MB, 2.4 ms [allocation failure].
[2268] 276161 ms: Scavenge 157.5 (185.5) -> 142.1 (185.5) MB, 2.7 ms (+ 2.4 ms in 18 steps since last GC) [allocation failure].
[2268] 276427 ms: Scavenge 159.8 (187.5) -> 144.3 (187.5) MB, 2.5 ms (+ 36.3 ms in 236 steps since last GC) [allocation failure].
[2268] 276494 ms: Mark-sweep 147.7 (188.5) -> 43.7 (121.5) MB, 20.1 ms (+ 45.1 ms in 298 steps since start of marking, biggest step 0.5 ms) [GC interrupt] [GC in old space requested].
Этот тип поведения возникает, когда я пытаюсь получить доступ к несуществующему URL
ab -c 100 -n 10000000 -k http://localhost:1337/invalid/url
Я не могу использовать node-inspector для отслеживания того, что вызывает такой интенсивный рост памяти, потому что он будет запрашивать полный gc, прежде чем делать снимок кучи.
Каковы мои возможности отслеживать, что вызывает такой быстрый рост памяти?
Как узнать, какие объекты выживают, но не выдерживают разметку gc?
Спасибо,
ОБНОВЛЕНИЕ 1 Таким образом, нет никакого способа увидеть содержимое, поглощенное средним возрастом. Вот подсказка, если вы видите быстрое увеличение памяти во время очистки, но затем она внезапно падает с отметкой & sweep, тогда это означает, что ваш код создает данные в большом пространстве. Например, длинные трассировки стека. Restify генерирует гигантские следы стека, которые должны быть отключены в процессе производства.
Ответы
Ответ 1
Насколько я знаю, нет простого способа увидеть контент среднего возраста. Однако, если вы видите быстрое увеличение памяти во время очистки, а затем внезапное падение, когда происходит разметка mark &, это обычно означает, что ваш код создает объекты в большом кучном пространстве. Например, длинные строки.
Rectify генерирует гигантские трассировки стека с каждым объектом Error, которые достаточно велики, чтобы не вписываться в новое пространство и поэтому игнорироваться с помощью mark & sweep.
Ответ 2
Вы можете попробовать запустить Node script с помощью опции -–expose-gc
:
node --expose-gc script.js
Это позволяет запускать сборку мусора вручную из JS:
global.gc();
Когда сбор мусора принудительно выполняется вручную, вы можете применить несколько методов моментального снимка:
- возьмите одну привязку раньше, одну привязку после GC
- затем примените оптимизацию
- затем одна привязка до, одна привязка после GC
Снимки позволяют отслеживать, что вызывает рост памяти.
Цель состоит в том, чтобы иметь лучший результат второй "привязки после GC",
по сравнению с первым "Snap after GC".