Skip to content

feat(memory): SKAINET_MEMORY_DEBUG — allocation-site tagging, use-after-close with the closing site, adapter log, leak reports (SKEEP-003 P2, S1.6) - #1075

Merged
michalharakal merged 1 commit into
developfrom
feature/1026-memory-debug-mode
Aug 23, 2026
Merged

michalharakal merged 1 commit into
developfrom
feature/1026-memory-debug-mode

Conversation

@michalharakal

Copy link
Copy Markdown
Contributor

Summary

SKEEP-003 slice S1.6 (milestone M1 #1002, PRD M1-F9, §4.7 / §8 item 4): SKAINET_MEMORY_DEBUG — the tool that would have found #782 in one run.

  • MemoryDebug: off by default (SKAINET_MEMORY_DEBUG=1 or -Dskainet.memory.debug=true; overrideEnabled for tests), costing one boolean read per allocation. On, it keeps a ledger — storage id, scope, bytes, origin TensorId, allocation site and closing site — plus per-scope live bytes and high-water marks.
  • Breakpoint-like hooks (§4.7): onAllocate, onClose, onAdapter, onLeak. A debugger or a test breaks on "an allocation whose origin matches layers[3].*", "storage Bump actions/upload-pages-artifact from 3 to 4 #412 closed", "an adapter larger than 50 MB" — ordinary callbacks, no JVMTI.
  • Storage wired in: allocations and closes are recorded (and the call site is passed into the trace event too), and checkAlive()'s message now names where the storage was allocated and closed — the difference between "something is closed" and "this weight was freed at model.close(), you are reading it from the KV path".
  • platformCallSite(): one StackWalker frame outside sk.ainet.lang.memory on JVM/Android, null elsewhere; platformMemoryDebugEnabled() reads the env var and property where the platform has them.

Evidence (MemoryDebugTest, 97/97 memory tests): nothing is recorded while debug mode is off; allocations are tagged with scope/origin/site; peaks survive frees; use-after-close names the tensor, scope and size; the close hook fires exactly once; adapter reporting works; leak reporting distinguishes an escaped storage from a closed one; report() renders peaks and live storages.

Test plan

Full local gate (scripts/pr-gate.sh, JDK 25) — all legs passed; results in the first comment.

Closes #1026

🤖 Generated with Claude Code

…er-close with the closing site, adapter log, leak reports (SKEEP-003 P2)

Milestone M1 (#1002), PRD M1-F9, SKEEP-003 §4.7 / §8 item 4: the tool
that would have found #782 in one run.

- MemoryDebug: off by default (SKAINET_MEMORY_DEBUG=1 or
  -Dskainet.memory.debug=true; overrideEnabled for tests), costing one
  boolean read per allocation. On, it keeps a bounded ledger — storage
  id, scope, bytes, origin TensorId, allocation site, closing site — plus
  per-scope live and high-water bytes.
- Breakpoint-like hooks (§4.7): onAllocate, onClose, onAdapter, onLeak.
  A debugger or a test breaks on "an allocation whose origin matches
  layers[3].*", "storage #412 closed", or "an adapter larger than X".
- Storage records allocations and closes into the ledger and passes the
  call site into the trace event too; checkAlive()'s message now names
  where the storage was allocated and closed, which is the difference
  between "something is closed" and "this weight was freed at
  model.close(), you are reading it from the KV path".
- platformCallSite(): a StackWalker frame outside sk.ainet.lang.memory on
  JVM/Android, null elsewhere; platformMemoryDebugEnabled() reads the env
  var and the property where there is one.
- MemoryDebugTest: nothing recorded while off; allocations tagged with
  scope/origin/site; peaks survive frees; use-after-close names the
  tensor, scope and size; close hook fires once; adapter reporting; leak
  reporting distinguishes an escaped storage from a closed one; report()
  renders peaks and live storages. 97/97 memory tests.

Closes #1026

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@michalharakal

Copy link
Copy Markdown
Contributor Author

Local gate scripts/pr-gate.sh (JDK 25) on 0dbb3cca: all legs passed — jvmTest · apiCheck · JS/Wasm · linuxX64Test · assemble · Java consumer API tests.

Targeted: sk.ainet.lang.memory.* 97/97.

@github-actions

Copy link
Copy Markdown

📖 Documentation Preview

The documentation has been built successfully for this PR.

Generated Files:

  • Operator documentation: docs/modules/operators/_generated_/
  • JSON schema output: operators.json

Artifacts:

  • Download the documentation-preview-1075 artifact to view the complete documentation locally.

This comment will be updated automatically when the PR is updated.

@michalharakal
michalharakal merged commit 0cd605e into develop Aug 23, 2026
16 checks passed
@michalharakal
michalharakal deleted the feature/1026-memory-debug-mode branch August 23, 2026 19:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[S1.6] P2: SKAINET_MEMORY_DEBUG=1 — allocation-site tags, use-after-close with closing stack, adapter log, ExecutionContext hooks, leak check

1 participant