spacr.qt.memory_budget¶
What spaCR is allowed to keep, and when it has to give it back.
Three settings, and the order matters. The HEADROOM FLOOR comes first: it says how much of the machine must stay free for everything else, and the other two are meaningless until something says when to apply them. Then the IDLE TIMEOUT, which says how long an unused thing may sit before it is dropped, and the CACHE CEILING, which says how much may be held at all.
WHAT THESE DO NOT DO IS UNLOAD A LIBRARY, and nothing here is named as
though it does. Measured on this machine: importing torch costs 477 MB,
deleting every torch entry from sys.modules and collecting returns 0 of
it, and 63 of its shared objects stay mapped. CPython has never supported
unloading a C extension. What CAN be returned is caches, model weights and
GPU allocations, so that is what these govern – and deferring an import
until first use is the honest form of “load when called”, which is why a
session that never opens a deep-learning module never pays the 477 MB.
Functions¶
|
How much memory the machine has free right now. |
|
Whether free memory has fallen below the floor. |
|
The suggested budget for a performance level. |
|
Which cache entries must go, oldest idle first. |
Module Contents¶
- spacr.qt.memory_budget.free_megabytes() float | None[source]¶
How much memory the machine has free right now.
- Returns:
megabytes, or
Nonewhen it cannot be measured – in which case the headroom floor cannot be enforced and says so rather than guessing.
- spacr.qt.memory_budget.headroom_is_short(floor_mb: float | None = None) bool[source]¶
Whether free memory has fallen below the floor.
- Parameters:
floor_mb – the floor; read from preferences when omitted.
- Returns:
Falsewhen memory cannot be measured – a cache that cannot be shown to be a problem is not dropped on suspicion.
- spacr.qt.memory_budget.recommended_for(level: str)[source]¶
The suggested budget for a performance level.
- Parameters:
level – one of
spacr.qt.preferences.PERFORMANCE_LEVELS.- Returns:
(idle_minutes, cache_mb, headroom_mb).
- spacr.qt.memory_budget.what_to_drop(entries, now: float, idle_minutes: float | None = None, ceiling_mb: int | None = None) list[source]¶
Which cache entries must go, oldest idle first.
- Parameters:
entries –
[(key, megabytes, last_used_epoch_seconds), ...].now – the current epoch time, passed in so a test can choose it.
idle_minutes – the idle timeout; from preferences when omitted.
ceiling_mb – the size ceiling; from preferences when omitted.
- Returns:
the keys to drop, in the order to drop them.
TWO REASONS, APPLIED IN ORDER. Anything idle longer than the timeout goes because nothing is using it. Then, if what remains is still over the ceiling, the least recently used go until it fits – so a cache under pressure gives up what it is least likely to want next rather than whatever it happens to reach first.
An entry is never dropped for being large alone: size decides the ORDER of a trim, and idleness decides whether one happens.