optimize-memory-allocation — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited optimize-memory-allocation (Agent Skill) and scored it 96/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 1 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 1 flagged
The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
The MCP fetches the data — allocation rankings, allocation flamegraphs, host metrics; you analyze: name the hot allocation sites, identify the pattern, recommend and apply the fix.
Java/JVM only. zymtrace memory-allocation profiling is supported only for the JVM — it reads the allocation profile, stacks weighted by bytes allocated (and object count), not on-CPU time. A non-Java workload has no allocation profile: stay in optimize-cpu-workloads for its on-CPU hotspots. For GPU/device memory use optimize-gpu-workloads. A service that's crashing/OOMKilled rather than churning is a profiler/backend problem — route to troubleshoot-zymtrace-profiler.
The common discipline — data-source policy, pre-flight, rank-first vs. drill-down, scope-to-own-code/ROI, the always-recommend-and-apply-the-fix rule, the output-template skeleton, severity sizing, and security — lives in shared/analysis-conventions.md. Read it. This skill adds the allocation-specific protocol and call-tree rendering on top.
Connection setup lives in configure-zymtrace-mcp; this skill assumes the MCP is connected.
JVM allocation profiling is off by default. Before analyzing, confirm the Java service actually has an allocation profile (try the allocation ranking / flamegraph for it). If it's empty, it isn't enabled yet — turn it on, wait for profiles to arrive, then analyze. Don't fabricate an analysis when there's no allocation data; enable and wait. Full reference: <https://docs.zymtrace.com/allocation-profiling>.
Prerequisite: the target runs a supported JVM — OpenJDK, Azul Zulu, or Azul Zing.
To enable, ask the user for these inputs, then apply:
Apply it one of two ways (per the docs):
<gateway-url>/api-docs/openapi.json (don't guess field names). This is also the Settings → Agent Config / Allocation Profiles page in the UI.-alloc-profile=<interval> (env ZYMTRACE_ALLOC_PROFILE), e.g. -alloc-profile=16mib, plus optional -use-jvmti (env ZYMTRACE_USE_JVMTI). See install-zymtrace-profiler. Use this when editing the profiler launch is easier than a live rule.Allocation is rarely free: high allocation rate drives GC frequency and pause time, and the allocation + collection work burns CPU that never shows up as your own hot function. So an allocation analysis pays off two ways — fewer/shorter GC pauses (latency) and reclaimed CPU (throughput / cost). When you've quantified the CPU recovered, dollarize it with the cost method in optimize-cpu-workloads § Cost: annualize the cores.
The MCP pulls the data; you do the analysis. Establish a data path first (pre-flight, in the shared doc), and confirm allocation profiling is enabled (above) — if the Java service has no allocation profile yet, enable it and wait for data before continuing.
hot_traces. Rank by bytes allocated over the window (show the figure per entry); include host and container names where the data has them. Mark unmodifiable runtime/library allocations (JIT, classloading, framework internals you can't change) non-actionable and drill into the highest user-owned site. See scope-to-own-code/ROI in the shared doc.Integer.valueOf, Long.valueOf, boxed types in collections / streams (Map<Integer,…>, Collectors.toList() on a boxed stream).String concatenation in loops, String.format, substring, getBytes, repeated toString(); StringBuilder growth.ArrayList/HashMap grown from default capacity (Arrays.copyOf, HashMap.resize) because no initial size was given.new byte[] / char[] per request for I/O, serialization, or codecs that could be pooled or reused.new ArrayList<>(n), new HashMap<>(expected, 1f).IntStream over Stream<Integer>.byte[]/ByteBuffer, reuse StringBuilder, stream instead of materializing.String.format with StringBuilder/append, gate debug-log string building behind level checks.The output-template skeleton is in the shared doc. The allocation Observed Call Tree block renders like this:
**Observed Call Tree — allocation profile** (<process / container / host / time range>)
<top-level frame> (<bytes / % of allocated>)
├── <child frame> (<bytes / %>)
│ └── <leaf alloc site> (<bytes / %>) ← allocating type/call, e.g. `Integer.valueOf`, `new byte[]`, `HashMap.resize`
└── <child frame> (<bytes / %>) ← hot allocation pathCall-tree conventions:
├── and └── for the hierarchy (matches what the MCP returns).← hot allocation path.agent/config/set or profiler flag) and waited for data before analyzing.(Plus the common Done checklist in the shared doc — template, every 🔴/🟡 has a Fix:, fix applied, follow-up question.)
shared/analysis-conventions.md.</content>
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.