1
0
mirror of https://github.com/misskey-dev/misskey.git synced 2026-07-25 15:35:14 +02:00

enhance(dev): tweak get-backend-memory

This commit is contained in:
syuilo
2026-07-16 15:59:41 +09:00
parent 212fcaf254
commit b5e470b6d4
4 changed files with 51 additions and 28 deletions

View File

@@ -384,8 +384,9 @@ if (heapSnapshotSection != null) {
lines.push('');
}
const artifactUrl = process.env.MK_MEMORY_HEAP_SNAPSHOT_ARTIFACT_URL_HEAD!.trim();
lines.push(`[Download representative V8 heap snapshot (head)](${artifactUrl})`);
const baseHeapSnapshotArtifactUrl = process.env.MK_MEMORY_HEAP_SNAPSHOT_ARTIFACT_URL_BASE!.trim();
const headHeapSnapshotArtifactUrl = process.env.MK_MEMORY_HEAP_SNAPSHOT_ARTIFACT_URL_HEAD!.trim();
lines.push(`Download representative V8 heap snapshot [base](${baseHeapSnapshotArtifactUrl}) / [head](${headHeapSnapshotArtifactUrl})`);
lines.push('');
const jsFootprintSection = renderJsFootprintSection(baseJsFootprint, headJsFootprint);

View File

@@ -28,8 +28,15 @@ export type MemoryReport = {
const [baseDirArg, headDirArg, baseOutputArg, headOutputArg] = process.argv.slice(2);
const HEAP_SNAPSHOT_BREAKDOWN_TOP_N = util.readIntegerEnv('MK_MEMORY_HEAP_SNAPSHOT_BREAKDOWN_TOP_N', heapSnapshotUtil.defaultHeapSnapshotBreakdownTopN, 1);
const HEAD_HEAP_SNAPSHOT_WORK_DIR = resolve('head-heap-snapshots');
const HEAD_HEAP_SNAPSHOT_OUTPUT_PATH = resolve('head-heap-snapshot.heapsnapshot');
const heapSnapshotLabels = ['base', 'head'] as const;
const HEAP_SNAPSHOT_WORK_DIRS = {
base: resolve('base-heap-snapshots'),
head: resolve('head-heap-snapshots'),
};
const HEAP_SNAPSHOT_OUTPUT_PATHS = {
base: resolve('base-heap-snapshot.heapsnapshot'),
head: resolve('head-heap-snapshot.heapsnapshot'),
};
// Use the head checkout's measurement harness for both targets so only the built backend differs.
const MEASURE_MEMORY_SCRIPT = resolve(import.meta.dirname, '../../packages/backend/scripts/measure-memory.mts');
@@ -119,11 +126,11 @@ async function measureRepo(label: string, repoDir: string, round: number, option
return JSON.parse(stdout) as MemorySample;
}
function headHeapSnapshotPath(round: number) {
return join(HEAD_HEAP_SNAPSHOT_WORK_DIR, `round-${round}.heapsnapshot`);
function heapSnapshotPath(label: typeof heapSnapshotLabels[number], round: number) {
return join(HEAP_SNAPSHOT_WORK_DIRS[label], `round-${round}.heapsnapshot`);
}
function selectRepresentativeHeadHeapSnapshotRound(samples: MemoryReport['samples'], summary: MemoryReport['summary']) {
function selectRepresentativeHeapSnapshotRound(samples: MemoryReport['samples'], summary: MemoryReport['summary']) {
const medianTotal = summary.afterGc.heapSnapshot?.categories?.total;
if (medianTotal == null || !Number.isFinite(medianTotal)) return null;
@@ -144,13 +151,13 @@ function selectRepresentativeHeadHeapSnapshotRound(samples: MemoryReport['sample
return selected?.round ?? null;
}
async function saveRepresentativeHeadHeapSnapshot(samples: MemoryReport['samples'], summary: MemoryReport['summary']) {
const round = selectRepresentativeHeadHeapSnapshotRound(samples, summary);
async function saveRepresentativeHeapSnapshot(label: typeof heapSnapshotLabels[number], samples: MemoryReport['samples'], summary: MemoryReport['summary']) {
const round = selectRepresentativeHeapSnapshotRound(samples, summary);
if (round == null) return;
await copyFile(headHeapSnapshotPath(round), HEAD_HEAP_SNAPSHOT_OUTPUT_PATH);
process.stderr.write(`Selected head heap snapshot round ${round} for artifact\n`);
await rm(HEAD_HEAP_SNAPSHOT_WORK_DIR, { recursive: true, force: true });
await copyFile(heapSnapshotPath(label, round), HEAP_SNAPSHOT_OUTPUT_PATHS[label]);
process.stderr.write(`Selected ${label} heap snapshot round ${round} for artifact\n`);
await rm(HEAP_SNAPSHOT_WORK_DIRS[label], { recursive: true, force: true });
}
async function main() {
@@ -162,8 +169,10 @@ async function main() {
const warmupRounds = util.readIntegerEnv('MK_MEMORY_COMPARE_WARMUP_ROUNDS', 1, 0);
const startedAt = new Date().toISOString();
await rm(HEAD_HEAP_SNAPSHOT_WORK_DIR, { recursive: true, force: true });
await rm(HEAD_HEAP_SNAPSHOT_OUTPUT_PATH, { force: true });
for (const label of heapSnapshotLabels) {
await rm(HEAP_SNAPSHOT_WORK_DIRS[label], { recursive: true, force: true });
await rm(HEAP_SNAPSHOT_OUTPUT_PATHS[label], { force: true });
}
const reports = {
base: {
@@ -178,7 +187,7 @@ async function main() {
for (let round = 1; round <= warmupRounds; round++) {
process.stderr.write(`Starting warmup round ${round}/${warmupRounds}\n`);
for (const label of ['base', 'head'] as const) {
for (const label of heapSnapshotLabels) {
await measureRepo(label, reports[label].dir, -round);
}
}
@@ -188,10 +197,7 @@ async function main() {
process.stderr.write(`Starting measurement round ${round}/${rounds}: ${order.join(' -> ')}\n`);
for (const label of order) {
const shouldSaveHeadHeapSnapshot = label === 'head';
const options = shouldSaveHeadHeapSnapshot
? { heapSnapshotSavePath: headHeapSnapshotPath(round) }
: {};
const options = { heapSnapshotSavePath: heapSnapshotPath(label, round) };
const sample = await measureRepo(label, reports[label].dir, round, options);
reports[label].samples.push({
...sample,
@@ -204,9 +210,11 @@ async function main() {
base: summarizeSamples(reports.base.samples),
head: summarizeSamples(reports.head.samples),
};
await saveRepresentativeHeadHeapSnapshot(reports.head.samples, summaries.head);
for (const label of heapSnapshotLabels) {
await saveRepresentativeHeapSnapshot(label, reports[label].samples, summaries[label]);
}
for (const label of ['base', 'head'] as const) {
for (const label of heapSnapshotLabels) {
const report = {
timestamp: new Date().toISOString(),
sampleCount: reports[label].samples.length,