We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Memory, Copies and Slow Code step 19 of 38
Measure Memory Growth and Always Stop Tracing
Write find_growth(fn, *, iterations), which measures how much traced
memory grows while fn runs iterations times. iterations is zero or
more. A positive result means traced memory grew during the measurement.
It does not prove a leak, and it is not every byte that fn allocated.
kept: list[bytes] = []
find_growth(lambda: kept.append(bytes(10_000)), iterations=50)
# about 502_700, for 50 more 10,000-byte objects plus a little overhead
What to write
Follow these steps in order:
- If tracing is already running, raise
RuntimeErrorat once. Do not callfn, and do not start, stop or clear tracing, because that session belongs to someone else. - Start tracing. Call
fn()once to warm up, then take the first snapshot. - Call
fn()exactlyiterationsmore times, then take the second snapshot. - Return the sum of every
size_diffinafter.compare_to(before, "lineno"), negative values included. - In a
finallyblock, stop the tracing you started, so that it stops even whenfnor a snapshot raises. Let that exception reach the caller unchanged.
With zero iterations the warm-up still runs once. The result does not have
to be zero, because taking snapshots allocates memory too. Do not round a
negative total up to zero, and do not force any particular number. You can
assume nothing else starts or stops tracing while find_growth runs. Your
code must pass mypy --strict.
What the driver does
Keep the workloads and solve as they are:
| Workload | What it does |
|---|---|
leaks |
Adds a list of 1,000 items to the global SINK, which keeps it |
churns |
Builds a list and clears it, without keeping it |
explodes |
Raises ValueError, so the warm-up call fails |
solve empties SINK, measures with N iterations, empties SINK again
and measures with 2N. The second run's lists stay in SINK until the next
call to solve. Tracing is off when solve starts.
The report contains:
grew: whether the first total is more than 100,000 bytes.scaled: whethergrewis true and the second total is at least 1.5 times the first.raised:"ValueError"if a workload raised it, otherwise"".tracing_stopped: whether tracing is off at the end.
These thresholds suit these small workloads. They are not rules for spotting a leak in real code.
Your code, saved here
Sign in to access your accepted solutions and saved draft history. You can keep reading the lesson without an account.
Sign in to your accountStuck?
Python reference solution
Sign in to track your attempts toward unlocking the reference solution.