Token导航 LogoToken导航

Agent Skill · 研究检索

alloc-profile(分配配置文件)

alloc-profile 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

alloc-profile 是研究检索类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为权限未标注;许可证信息还不明确,第三方扫描有提醒项,按安装量在研究检索类的 73,675 个 Skill 里排第 72,323。

总安装 188周安装 8GitHub Stars 47,081下载 66核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
unknown

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:alloc-profile(分配配置文件)
来源仓库:https://github.com/clickhouse/clickhouse
仓库路径:skills/alloc-profile
安装命令:
npx skills add https://github.com/clickhouse/clickhouse --skill alloc-profile
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/clickhouse/clickhouse --skill alloc-profile

这个 Skill 是做什么的

研究检索类 Skill 主要解决「找资料、核对事实、把来源整理清楚」的问题,通常会让助手先检索再总结。

alloc-profile 用于分析分配配置文件,支持 jemalloc、async-profiler 等工具的堆栈格式。适合在 Codex、Claude、Cursor、Gemini CLI 中分析内存分配性能时使用。可自动定位 .collapsed 文件,解析帧堆栈和数值(字节或采样数)。

安装前需确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。支持命令行参数指定文件路径,未指定时自动搜索当前目录下的 .collapsed 文件。

来源仓库内路径:skills/alloc-profile

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/clickhouse/clickhouse --skill alloc-profile;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    权限没有明确标注,第一次使用时只给一个无关紧要的任务,观察它到底读了哪些文件和网络。

常见问题

6 条

alloc-profile 怎么安装?

在终端执行 npx skills add https://github.com/clickhouse/clickhouse --skill alloc-profile。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

alloc-profile 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

alloc-profile 需要什么权限?

权限级别没有明确标注。第一次使用时建议只给无关紧要的任务,观察它实际读写了哪些内容。

alloc-profile 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

alloc-profile 用的人多吗?

公开数据是累计安装 188 次,近一周安装 8 次,下载 66 次,GitHub 47,081 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

alloc-profile 安全吗?

第三方扫描有提醒项,说明存在需要人工确认的行为。安装前请打开源码看清它读了什么、联网到哪里。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 来源仓库有 47,081 星,维护活跃度相对可查。

先想清楚的地方

  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方扫描存在提醒项或未通过项,需要人工逐条确认。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理研究检索类任务、又不想每次都手写提示词的人。

不太适合

  • 需要明确授权才能用到公司项目里的场景。
  • 需要厂商级技术支持和 SLA 的生产系统。

研究检索类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
find-skills

寻找技能 · Codex、Claude

31,199,81316,486操作浏览器MIT有提醒
self-improving-agent

自我改进 Agent · OpenClaw

16,464,0023,396接触敏感数据MIT-0通过
soultrace

灵魂追踪 · Codex、Claude

7,588,94412需要联网未明确有提醒
self-improving

自我完善 · OpenClaw

6,829,2841,046需要联网MIT-0通过
microsoft-foundry

微软代工厂 · Codex、Claude

6,614,144764调用外部服务未明确有提醒
alloc-profile

分配配置文件 · 本页

18847,081权限未标注未明确有提醒

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

Allocation Profile Analysis Skill

Analyze an allocation profile file in collapsed stack format (as produced by jemalloc, async-profiler, perf). Each line has the form:

frame1;frame2;...;frameN VALUE

where VALUE is the number of bytes (or samples, depending on the profiler) attributed to that stack trace.

Arguments

  • $0 (optional): Path to the .collapsed file. If not provided, search for .collapsed files in the current directory and ask the user to choose.

Step 1 — Locate the profile file

Use Task tool with subagent_type=Bash to locate the file:

If $ARGUMENTS is provided, use it directly. Otherwise, run:

find . -maxdepth 3 -name "*.collapsed" -o -name "*.folded" | sort -t_ -k1,1

Report the candidates to the user and ask with AskUserQuestion:

  • Question: "Which profile file do you want to analyze?"
  • Options: one per found file (show filename and size), plus "Other — enter path manually"

Once the file path is known, pass it to all subsequent steps.

Step 2 — Parallel initial analysis

Launch the following three Task agents IN PARALLEL (single message, three tool calls) all with run_in_background: true. Then call TaskOutput for ALL three agents (also in parallel, single message) before proceeding to Step 3. Do NOT start Step 3 until every agent has finished.

Fallback: If any agent fails (e.g., reports lacking Bash permission), re-run its Python script directly using the Bash tool in the main context.

Agent A — Summary statistics (subagent_type=Bash)

Run this Python script to compute summary statistics:

python3 - <<'EOF'
import sys, os, re
filepath = "PATH_TO_FILE"  # substituted by skill
lines = open(filepath).read().splitlines()
traces = []
for line in lines:
    line = line.strip()
    if not line:
        continue
    parts = line.rsplit(' ', 1)
    if len(parts) != 2:
        continue
    try:
        traces.append((int(parts[1]), parts[0]))
    except ValueError:
        continue

total = sum(v for v, _ in traces)
traces.sort(reverse=True)

# Noise filters — keep in sync with Agent C
JEMALLOC_PREFIXES = (
    "prof_backtrace", "prof_alloc_prep", "prof_tctx", "prof_",
    "imalloc", "ialloc", "irallocx", "imallocx",
    "arena_malloc", "arena_palloc", "arena_ralloc", "arena_",
    "tcache_alloc", "tcache_",
    "large_malloc", "large_palloc",
    "chunk_alloc", "huge_malloc", "huge_palloc",
    "je_malloc", "je_calloc", "je_realloc", "je_rallocx", "je_mallocx",
    "je_posix_memalign", "je_aligned_alloc",
    "malloc_default", "calloc",
)
ALLOC_SUBSTRINGS = (
    "operator new", "operator new[]",
    "__libcpp_operator_new",
    "__libc_malloc", "__libc_calloc", "_int_malloc",
    "posix_memalign", "aligned_alloc",
    "do_rallocx", "do_mallocx",
    "mi_malloc", "mi_calloc",
    "__cxx_global_var_init", "__cxa_thread_atexit_impl",
    "DB::Memory<", "Memory::newImpl", "Allocator<false", "Allocator<true",
    "allocNoTrack",
    "PODArrayBase::realloc", "PODArrayBase::alloc",
    "CRYPTO_malloc",
    "std::__detail::_Hash_node", "std::_Rb_tree",
    "std::vector<", "std::string::",
    # STL and PODArray wrappers — noise for leaf analysis
    "std::__1::",
    "DB::PODArrayBase",
)

def is_noise(frame):
    return (any(frame.startswith(p) for p in JEMALLOC_PREFIXES) or
            any(s in frame for s in ALLOC_SUBSTRINGS))

def shorten(frame):
    return re.sub(r'<[^>]{40,}>', '<...>', frame)

print(f"=== SUMMARY ===")
print(f"File: {filepath}")
print(f"Total allocated: {total:,} bytes  ({total/1024/1024:.2f} MB)  ({total/1024/1024/1024:.3f} GB)")
print(f"Unique stack traces: {len(traces)}")
print()
print("=== TOP 25 STACK TRACES ===")
for i, (v, stack) in enumerate(traces[:25], 1):
    frames = [f for f in stack.split(';') if f]
    meaningful = [f for f in frames if not is_noise(f)]
    tail_frames = meaningful[-4:] if meaningful else frames[-4:]
    tail = ' <- '.join(shorten(f) for f in reversed(tail_frames))
    print(f"{i:>3}. {v/1024/1024:>8.2f} MB  ({100*v/total:>5.1f}%)  {tail[:120]}")
print()
print("=== FULL STACKS FOR TOP 10 ===")
for i, (v, stack) in enumerate(traces[:10], 1):
    frames = [f for f in stack.split(';') if f]
    print(f"\n--- #{i}: {v/1024/1024:.2f} MB ({100*v/total:.1f}%) ---")
    for depth, frame in enumerate(reversed(frames), 1):
        noise_mark = "  [noise]" if is_noise(frame) else ""
        print(f"  [{depth:>2}] {shorten(frame)}{noise_mark}")
EOF

Agent B — Outermost meaningful frame aggregation (subagent_type=Bash)

Run this Python script to aggregate by the outermost (shallowest) meaningful frame — the operation that initiated the allocation. This answers "why did this allocation happen?" (e.g., loading data parts, executing a query, loading a dictionary), complementing Agent C which answers "what code allocated?":

python3 - <<'EOF'
import sys, re
from collections import defaultdict
filepath = "PATH_TO_FILE"  # substituted by skill

lines = open(filepath).read().splitlines()
traces = []
for line in lines:
    line = line.strip()
    if not line:
        continue
    parts = line.rsplit(' ', 1)
    if len(parts) != 2:
        continue
    try:
        traces.append((int(parts[1]), parts[0]))
    except ValueError:
        continue

total = sum(v for v, _ in traces)

# Frames to skip when looking for the outermost meaningful frame:
# thread pool scaffolding, libc entry points, raw addresses, lambda wrappers
SKIP_OUTER = (
    "0000", "_start", "__libc_start", "__GI___clone",
    "start_thread", "clone3",
    "ThreadPoolImpl", "ThreadFromGlobalPool",
    "std::__1::__function", "std::__1::__invoke",
    "decltype", "void std::__1::__function",
    "std::__1::__packaged_task_function",
    "DB::ThreadPool", "DB::GlobalThreadPool",
    "DB::threadFunction",
    "BaseDaemon", "SignalListener",
    "Poco::ThreadImpl::runnableEntry",
    "Poco::PooledThread::run",
    "main",
    "DB::Server::run",
    "Poco::Util::Application::run",
)

def is_skip_outer(frame):
    return any(frame.startswith(p) for p in SKIP_OUTER) or frame.startswith("(")

def shorten(frame):
    # Collapse long templates, preserve (anonymous namespace), strip args
    s = re.sub(r'<[^>]{40,}>', '<...>', frame)
    s = s.replace('(anonymous namespace)', '{anon}')
    s = re.sub(r'\(.*', '', s)
    s = s.replace('{anon}', '(anonymous namespace)')
    return s[:120]

by_outer = defaultdict(int)

for v, stack in traces:
    frames = [f for f in stack.split(';') if f]
    outer = None
    for f in frames:
        if not f or is_skip_outer(f):
            continue
        outer = f
        break
    if outer is None:
        outer = frames[0] if frames else "(unknown)"
    by_outer[shorten(outer)] += v

print("=== TOP 25 OUTERMOST MEANINGFUL FRAMES (operation that initiated allocation) ===")
for fn, v in sorted(by_outer.items(), key=lambda x: -x[1])[:25]:
    mb = v / 1024 / 1024
    pct = 100 * v / total
    bar = "\u2588" * int(pct / 2)
    print(f"  {mb:>10.2f} MB  {pct:>5.1f}%  {bar:<20}  {fn}")
EOF

Agent C — Leaf (allocating) function aggregation (subagent_type=Bash)

Run this Python script to aggregate by the deepest (innermost) frame — the actual allocation call:

python3 - <<'EOF'
import sys, re
from collections import defaultdict
filepath = "PATH_TO_FILE"  # substituted by skill

lines = open(filepath).read().splitlines()
traces = []
for line in lines:
    line = line.strip()
    if not line:
        continue
    parts = line.rsplit(' ', 1)
    if len(parts) != 2:
        continue
    try:
        traces.append((int(parts[1]), parts[0]))
    except ValueError:
        continue

total = sum(v for v, _ in traces)

# Aggregate by last meaningful frame (the allocating function)
by_leaf = defaultdict(int)
by_caller = defaultdict(int)  # caller of the leaf

# jemalloc profiling infrastructure — always at the bottom of every stack
JEMALLOC_PREFIXES = (
    "prof_backtrace", "prof_alloc_prep", "prof_tctx", "prof_",
    "imalloc", "ialloc", "irallocx", "imallocx",
    "arena_malloc", "arena_palloc", "arena_ralloc", "arena_",
    "tcache_alloc", "tcache_",
    "large_malloc", "large_palloc",
    "chunk_alloc", "huge_malloc", "huge_palloc",
    "je_malloc", "je_calloc", "je_realloc", "je_rallocx", "je_mallocx",
    "je_posix_memalign", "je_aligned_alloc",
    "malloc_default", "calloc",
)
# libc / C++ allocator wrappers that add no information
ALLOC_SUBSTRINGS = (
    "operator new", "operator new[]",
    "__libcpp_operator_new",
    "__libc_malloc", "__libc_calloc", "_int_malloc",
    "posix_memalign", "aligned_alloc",
    "do_rallocx", "do_mallocx",
    "mi_malloc", "mi_calloc",
    # C++ static/thread-local initialization wrappers
    "__cxx_global_var_init", "__cxa_thread_atexit_impl",
    # ClickHouse allocator wrappers — informative only as callers, not as leaf
    "DB::Memory<", "Memory::newImpl", "Allocator<false", "Allocator<true",
    "allocNoTrack",
    "PODArrayBase::realloc", "PODArrayBase::alloc",
    # Third-party allocators
    "CRYPTO_malloc",
    # STL internals
    "std::__detail::_Hash_node", "std::_Rb_tree",
    "std::vector<", "std::string::",
    # STL and PODArray wrappers — noise for leaf analysis
    "std::__1::",
    "DB::PODArrayBase",
)

def is_noise(frame):
    return (any(frame.startswith(p) for p in JEMALLOC_PREFIXES) or
            any(s in frame for s in ALLOC_SUBSTRINGS))

def meaningful_leaf(frames):
    # Walk from innermost (last) frame upward, skipping allocator/profiling noise.
    # In jemalloc collapsed format frames are outermost-first, so the bottom of
    # the stack (profiling infra + raw allocators) is at the end of the list.
    for f in reversed(frames):
        if f and not is_noise(f):
            return f
    return frames[-1] if frames else "(unknown)"

def meaningful_caller(frames):
    """Second non-noise frame from the bottom."""
    found_leaf = False
    for f in reversed(frames):
        if f and not is_noise(f):
            if found_leaf:
                return f
            found_leaf = True
    return None

def shorten(frame):
    s = re.sub(r'<[^>]{40,}>', '<...>', frame)
    s = s.replace('(anonymous namespace)', '{anon}')
    s = re.sub(r'\(.*', '', s)
    s = s.replace('{anon}', '(anonymous namespace)')
    return s[:120]

for v, stack in traces:
    frames = [f for f in stack.split(';') if f]
    leaf = meaningful_leaf(frames)
    by_leaf[shorten(leaf)] += v
    caller = meaningful_caller(frames)
    if caller:
        by_caller[shorten(caller)] += v

print("=== TOP 25 ALLOCATING FUNCTIONS (first non-trivial frame from bottom) ===")
for label, bucket in [("Leaf (allocator call site)", by_leaf),
                       ("Caller of leaf", by_caller)]:
    print(f"\n--- {label} ---")
    for fn, v in sorted(bucket.items(), key=lambda x: -x[1])[:25]:
        mb = v / 1024 / 1024
        pct = 100 * v / total
        print(f"  {mb:>8.2f} MB  {pct:>5.1f}%  {fn}")
EOF

Step 3 — Synthesize results and perform subsystem grouping

MANDATORY: All three agents from Step 2 must have completed (TaskOutput returned) before this step.

Using the outputs from Agent A (top stacks with full traces), Agent B (outermost frame — the initiating operation), and Agent C (leaf function — the allocating code), you (the main LLM) produce a structured report. Agent B gives you the "why" (what operation triggered allocations) and Agent C gives you the "how" (what code did the allocating). Combined with Agent A's full stacks, you can semantically group allocations into subsystems — e.g., AggregatedDataVariants::init called from HashedDictionary::loadData is "Dictionary Loading", not "Aggregation"; Arena::addMemoryChunk inside a merge pipeline is "Merges", not "Arena".

Your report should include:

  1. Summary statistics (total, trace count)
  2. Top allocators table (top 15 stack traces with readable short description)
  3. Subsystem breakdown with bar chart — group every top-25 trace (and the leaf function data) into semantic subsystems based on the full call path context. Use categories like: Part Loading, Dictionary Loading, Query Execution, Backup & Restore, Merges & Mutations, File Cache, IO Buffers, Replication, System Logs, etc. Show an ASCII bar chart. Traces that don't fit neatly into a category go into "(other)".
  4. Top 3–5 actionable findings — e.g.:

- Which subsystem unexpectedly dominates - Any single allocation that is disproportionately large (>5% of total) - Repeated patterns (e.g., many system log types each reserving large buffers) - Signs of fragmentation or excessive reallocation (do_rallocx / PODArray::realloc heavy)

  1. Follow-up drill-down questions the user may want to investigate

Step 4 — Offer drill-down options

After presenting the summary, use AskUserQuestion:

Question: "What would you like to do next?"

  • Option 1: "Drill into a specific subsystem" Description: "Show all stack traces for a chosen component (e.g., MergeTree, SystemLog)" → Ask which subsystem with a follow-up AskUserQuestion → Launch Task (subagent_type=Bash) in the background (run_in_background: true) with a Python script that:

- Filters all traces whose stack contains any keyword matching the chosen subsystem - Sorts by value descending - Prints each trace as: MB (pct%) | frame1 ← frame2 ←... ← frameN - Also prints the full call stack for the top 5 matches - Prints a sub-total for the subsystem → Use TaskOutput to wait, then pass output to a general-purpose Task agent for a concise summary

  • Option 2: "Show full stacks for top N traces" Description: "Print complete call stacks for the largest N allocations" → Ask N with a follow-up AskUserQuestion (suggest 10 as default) → Launch Task (subagent_type=Bash) in the background with a Python script that:

- Parses the file, sorts by value, takes top N - For each: prints rank, MB, %, and the full reversed call stack with depth indices → Use TaskOutput to wait, then pass output to a general-purpose Task agent for a concise narrative summary

  • Option 3: "Search for a keyword in stacks" Description: "Filter traces containing a specific function or class name" → Ask for the keyword via AskUserQuestion → Launch two Task agents in parallel (run_in_background: true):

- Agent X (subagent_type=Bash): filter and aggregate all matching traces — sum total, count, top 20 by size, full stacks for top 5 - Agent Y (subagent_type=Bash): find related keywords by scanning all frames containing the keyword and extracting their neighboring frames (co-occurring functions), to suggest related call paths → Use TaskOutput (both) then pass combined output to a general-purpose Task agent for synthesis

  • Option 4: "Generate flamegraph SVG" Description: "Render an SVG flamegraph using flamegraph.pl (must be installed)" → Launch Task (subagent_type=Bash) in the background: flamegraph.pl --title "Allocation Profile" --countname bytes --width 1800 \ PATH_TO_FILE > /tmp/alloc_flamegraph.svg → Use TaskOutput to wait for completion → Report the output path /tmp/alloc_flamegraph.svg and remind user to open it in a browser
  • Option 5: "Done" Description: "Exit without further analysis"

IMPORTANT: For every drill-down option (1–4):

  • Always run the analysis inside a Task subagent — never process the file in the main context
  • Always run the Bash analysis task in the background with run_in_background: true and wait with TaskOutput
  • Always pass raw output through a general-purpose Task agent for a concise, human-readable summary before showing it to the user

Repeat drill-down (return to the AskUserQuestion) until user selects "Done".

Notes

  • Values in collapsed format are live (in-use) bytes — jemalloc heap profiles track allocations minus deallocations, so values reflect currently live memory at the time of the dump
  • High values directly indicate live memory pressure at those call sites
  • Frames are listed outermost (thread root) first, innermost (allocator) last — the analysis scripts reverse this for readability
  • Symbol names may be mangled if the binary lacks debug info; use jeprof --demangle or pipe through c++filt
  • ALWAYS use Task subagents for all analysis steps — profile files can be hundreds of MB and must not be read into the main context
  • All Python analysis scripts are self-contained and can be run directly with python3 -

Examples

  • /alloc-profile — Find .collapsed files and prompt for selection
  • /alloc-profile jemalloc-profile-2026-02-19T13-08-59-825Z.collapsed — Analyze a specific file
  • /alloc-profile /tmp/prod-heap-dump.collapsed — Analyze an absolute path

平台分布

Codex

32.99%
按下载量换算22

Claude

33.75%
按下载量换算22

Cursor

17.85%
按下载量换算12

Gemini CLI

8.79%
按下载量换算6

安全审计

Gen Agent Trust Hub

可疑

Socket

通过

Snyk

通过

权限和风险

权限未标注

当前来源未能明确判断权限范围,默认进入异常复核队列。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在提醒或未通过项,安装前请自行复核。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills