diff options
| author | syuilo <4439005+syuilo@users.noreply.github.com> | 2026-01-22 14:32:57 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-01-22 14:32:57 +0900 |
| commit | 2fa6ecc7efaaf9b9d189cdd3a3ebbb9171c86078 (patch) | |
| tree | 765b336c2f5b27e1df1f5ee1e14f4bb6a8e54684 | |
| parent | enhance(dev): improve mem report (#17117) (diff) | |
| download | misskey-2fa6ecc7efaaf9b9d189cdd3a3ebbb9171c86078.tar.gz misskey-2fa6ecc7efaaf9b9d189cdd3a3ebbb9171c86078.tar.bz2 misskey-2fa6ecc7efaaf9b9d189cdd3a3ebbb9171c86078.zip | |
enhance(dev): improve mem report (#17118)
* wip
* wip
* Update report-backend-memory.yml
* Update report-backend-memory.yml
* Update .github/workflows/report-backend-memory.yml
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
| -rw-r--r-- | .github/workflows/report-backend-memory.yml | 87 | ||||
| -rw-r--r-- | packages/backend/scripts/measure-memory.mjs | 37 | ||||
| -rw-r--r-- | packages/backend/src/boot/entry.ts | 14 | ||||
| -rw-r--r-- | packages/backend/src/env.ts | 1 |
4 files changed, 99 insertions, 40 deletions
diff --git a/.github/workflows/report-backend-memory.yml b/.github/workflows/report-backend-memory.yml index 47ec652cfd..451a8cf9e6 100644 --- a/.github/workflows/report-backend-memory.yml +++ b/.github/workflows/report-backend-memory.yml @@ -54,31 +54,48 @@ jobs: BASE_MEMORY=$(cat ./artifacts/memory-base.json) HEAD_MEMORY=$(cat ./artifacts/memory-head.json) - calc() { - BASE=$(echo "$BASE_MEMORY" | jq -r '.memory.'"$1"' // 0') - HEAD=$(echo "$HEAD_MEMORY" | jq -r '.memory.'"$1"' // 0') + variation() { + calc() { + BASE=$(echo "$BASE_MEMORY" | jq -r ".${1}.${2} // 0") + HEAD=$(echo "$HEAD_MEMORY" | jq -r ".${1}.${2} // 0") - DIFF=$((HEAD - BASE)) - if [ "$BASE" -gt 0 ]; then - DIFF_PERCENT=$(echo "scale=2; ($DIFF * 100) / $BASE" | bc) - else - DIFF_PERCENT=0 - fi + DIFF=$((HEAD - BASE)) + if [ "$BASE" -gt 0 ]; then + DIFF_PERCENT=$(echo "scale=2; ($DIFF * 100) / $BASE" | bc) + else + DIFF_PERCENT=0 + fi - # Convert KB to MB for readability - BASE_MB=$(echo "scale=2; $BASE / 1024" | bc) - HEAD_MB=$(echo "scale=2; $HEAD / 1024" | bc) - DIFF_MB=$(echo "scale=2; $DIFF / 1024" | bc) + # Convert KB to MB for readability + BASE_MB=$(echo "scale=2; $BASE / 1024" | bc) + HEAD_MB=$(echo "scale=2; $HEAD / 1024" | bc) + DIFF_MB=$(echo "scale=2; $DIFF / 1024" | bc) - echo "$1-base=$BASE_MB" >> "$GITHUB_OUTPUT" - echo "$1-head=$HEAD_MB" >> "$GITHUB_OUTPUT" - echo "$1-diff=$DIFF_MB" >> "$GITHUB_OUTPUT" - echo "$1-diff_percent=$DIFF_PERCENT" >> "$GITHUB_OUTPUT" + JSON=$(jq -c -n \ + --arg base "$BASE_MB" \ + --arg head "$HEAD_MB" \ + --arg diff "$DIFF_MB" \ + --arg diff_percent "$DIFF_PERCENT" \ + '{base: $base, head: $head, diff: $diff, diff_percent: $diff_percent}') + + echo "$JSON" + } + + JSON=$(jq -c -n \ + --argjson VmRSS "$(calc $1 VmRSS)" \ + --argjson VmHWM "$(calc $1 VmHWM)" \ + --argjson VmSize "$(calc $1 VmSize)" \ + '{VmRSS: $VmRSS, VmHWM: $VmHWM, VmSize: $VmSize}') + + echo "$JSON" } - calc VmRSS - calc VmHWM - calc VmSize + JSON=$(jq -c -n \ + --argjson beforeGc "$(variation beforeGc)" \ + --argjson afterGc "$(variation afterGc)" \ + '{beforeGc: $beforeGc, afterGc: $afterGc}') + + echo "res=$JSON" >> "$GITHUB_OUTPUT" - id: build-comment name: Build memory comment run: | @@ -88,15 +105,33 @@ jobs: echo "$HEADER" > ./output.md echo >> ./output.md - echo "| Metric | base | head | Diff |" >> ./output.md - echo "|--------|------|------|------|" >> ./output.md - echo "| RSS | ${{ steps.compare.outputs.VmRSS-base }} MB | ${{ steps.compare.outputs.VmRSS-head }} MB | ${{ steps.compare.outputs.VmRSS-diff }} MB (${{ steps.compare.outputs.VmRSS-diff_percent }}%) |" >> ./output.md - echo "| HWM | ${{ steps.compare.outputs.VmHWM-base }} MB | ${{ steps.compare.outputs.VmHWM-head }} MB | ${{ steps.compare.outputs.VmHWM-diff }} MB (${{ steps.compare.outputs.VmHWM-diff_percent }}%) |" >> ./output.md - echo "| VMS | ${{ steps.compare.outputs.VmSize-base }} MB | ${{ steps.compare.outputs.VmSize-head }} MB | ${{ steps.compare.outputs.VmSize-diff }} MB (${{ steps.compare.outputs.VmSize-diff_percent }}%) |" >> ./output.md + table() { + line() { + BASE=$(echo "${{ steps.compare.outputs.res }}" | jq -r ".${1}.${2}.base") + HEAD=$(echo "${{ steps.compare.outputs.res }}" | jq -r ".${1}.${2}.head") + DIFF=$(echo "${{ steps.compare.outputs.res }}" | jq -r ".${1}.${2}.diff") + DIFF_PERCENT=$(echo "${{ steps.compare.outputs.res }}" | jq -r ".${1}.${2}.diff_percent") + + echo "| ${2} | ${BASE} MB | ${HEAD} MB | ${DIFF} MB (${DIFF_PERCENT}%) |" >> ./output.md + } + + echo "| Metric | base | head | Diff |" >> ./output.md + echo "|--------|------|------|------|" >> ./output.md + line $1 VmRSS + line $1 VmHWM + line $1 VmSize + } + + echo "### Before GC" >> ./output.md + table beforeGc + echo >> ./output.md + + echo "### After GC" >> ./output.md + table afterGc echo >> ./output.md # Determine if this is a significant change (more than 5% increase) - if [ "$(echo "${{ steps.compare.outputs.VmRSS-diff_percent }} > 5" | bc)" -eq 1 ]; then + if [ "$(echo "${{ steps.compare.outputs.res }}" | jq -r '.afterGc.VmRSS.diff_percent | tonumber > 5')" = "true" ]; then echo "⚠️ **Warning**: Memory usage has increased by more than 5%. Please verify this is not an unintended change." >> ./output.md echo >> ./output.md fi diff --git a/packages/backend/scripts/measure-memory.mjs b/packages/backend/scripts/measure-memory.mjs index 82a5a0bf0b..749f550bcc 100644 --- a/packages/backend/scripts/measure-memory.mjs +++ b/packages/backend/scripts/measure-memory.mjs @@ -60,9 +60,9 @@ async function measureMemory() { ...process.env, NODE_ENV: 'production', MK_DISABLE_CLUSTERING: '1', - MK_FORCE_GC: '1', }, stdio: ['pipe', 'pipe', 'pipe', 'ipc'], + execArgv: [...process.execArgv, '--expose-gc'], }); let serverReady = false; @@ -104,9 +104,21 @@ async function measureMemory() { // Wait for memory to settle await setTimeout(MEMORY_SETTLE_TIME); - // Get memory usage from the server process via /proc const pid = serverProcess.pid; - const memoryInfo = await getMemoryUsage(pid); + + const beforeGc = await getMemoryUsage(pid); + + serverProcess.send('gc'); + + await new Promise((resolve) => { + serverProcess.once('message', (message) => { + if (message === 'gc ok') resolve(); + }); + }); + + await setTimeout(1000); + + const afterGc = await getMemoryUsage(pid); // Stop the server serverProcess.kill('SIGTERM'); @@ -129,7 +141,8 @@ async function measureMemory() { const result = { timestamp: new Date().toISOString(), - memory: memoryInfo, + beforeGc, + afterGc, }; return result; @@ -144,19 +157,23 @@ async function main() { } // Calculate averages - const avgMemory = structuredClone(keys); + const beforeGc = structuredClone(keys); + const afterGc = structuredClone(keys); for (const res of results) { - for (const key of Object.keys(avgMemory)) { - avgMemory[key] += res.memory[key]; + for (const key of Object.keys(keys)) { + beforeGc[key] += res.beforeGc[key]; + afterGc[key] += res.afterGc[key]; } } - for (const key of Object.keys(avgMemory)) { - avgMemory[key] = Math.round(avgMemory[key] / SAMPLE_COUNT); + for (const key of Object.keys(keys)) { + beforeGc[key] = Math.round(beforeGc[key] / SAMPLE_COUNT); + afterGc[key] = Math.round(afterGc[key] / SAMPLE_COUNT); } const result = { timestamp: new Date().toISOString(), - memory: avgMemory, + beforeGc, + afterGc, }; // Output as JSON to stdout diff --git a/packages/backend/src/boot/entry.ts b/packages/backend/src/boot/entry.ts index 56b339b6aa..3a33d198a5 100644 --- a/packages/backend/src/boot/entry.ts +++ b/packages/backend/src/boot/entry.ts @@ -86,9 +86,17 @@ if (!envOption.disableClustering) { ev.mount(); } -if (envOption.forceGc && global.gc != null) { - global.gc(); -} +process.on('message', msg => { + if (msg === 'gc') { + if (global.gc != null) { + logger.info('Manual GC triggered'); + global.gc(); + if (process.send != null) process.send('gc ok'); + } else { + logger.warn('Manual GC requested but gc is not available. Start the process with --expose-gc to enable this feature.'); + } + } +}); readyRef.value = true; diff --git a/packages/backend/src/env.ts b/packages/backend/src/env.ts index 9957938467..ba44cfa2e6 100644 --- a/packages/backend/src/env.ts +++ b/packages/backend/src/env.ts @@ -11,7 +11,6 @@ const envOption = { verbose: false, withLogTime: false, quiet: false, - forceGc: false, }; for (const key of Object.keys(envOption) as (keyof typeof envOption)[]) { |