> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-parallel-read-in-order-multi-part.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Página que detalla el perfilado de asignaciones en ClickHouse

# Perfilado de asignaciones

ClickHouse usa [jemalloc](https://github.com/jemalloc/jemalloc) como asignador global. Jemalloc incluye herramientas para el muestreo y el perfilado de asignaciones.

ClickHouse y Keeper permiten controlar el muestreo mediante configuraciones, settings de consulta, comandos `SYSTEM` y comandos de cuatro letras (4LW) en Keeper. Hay varias formas de inspeccionar los resultados:

* Recopilar muestras en `system.trace_log` con el tipo `JemallocSample` para analizar cada consulta.
* Ver estadísticas de memoria en tiempo real y obtener perfiles de heap a través de la [UI web de jemalloc](#jemalloc-web-ui) integrada (26.2+).
* Consultar el perfil actual de heap directamente desde SQL mediante [`system.jemalloc_profile_text`](#fetching-heap-profiles-from-sql) (26.2+).
* Analizar la fragmentación de memoria desde SQL mediante [`system.jemalloc_sampled_allocations`](#analyzing-fragmentation-from-sql) (26.9+).
* Volcar perfiles de heap a disco y analizarlos con [`jeprof`](#analyzing-heap-profile-files-with-jeprof).

<Note>
  Esta guía se aplica a las versiones 25.9+.
  Para versiones anteriores, consulte [el perfilado de asignaciones para versiones anteriores a la 25.9](/es/concepts/features/performance/allocation-profiling-old).
</Note>

<h2 id="sampling-allocations">
  Muestreo de asignaciones
</h2>

Para muestrear y perfilar las asignaciones, inicie ClickHouse/Keeper con la opción de configuración `jemalloc_enable_global_profiler` habilitada:

```xml theme={null}
<clickhouse>
    <jemalloc_enable_global_profiler>1</jemalloc_enable_global_profiler>
</clickhouse>
```

`jemalloc` realizará un muestreo de las asignaciones y almacenará la información internamente.

También puede habilitar el muestreo por consulta mediante la configuración `jemalloc_enable_profiler`.

<Warning>
  **Advertencia**

  Dado que ClickHouse es una aplicación que realiza muchas asignaciones de memoria, el muestreo de jemalloc puede introducir una sobrecarga de rendimiento.
</Warning>

<h2 id="storing-jemalloc-samples-in-system-trace-log">
  Almacenar muestras de jemalloc en `system.trace_log`
</h2>

Puede almacenar muestras de jemalloc en `system.trace_log` con el tipo `JemallocSample`.
Para habilitarlo globalmente, use la configuración `jemalloc_collect_global_profile_samples_in_trace_log`:

```xml theme={null}
<clickhouse>
    <jemalloc_collect_global_profile_samples_in_trace_log>1</jemalloc_collect_global_profile_samples_in_trace_log>
</clickhouse>
```

<Warning>
  **Advertencia**

  Dado que ClickHouse es una aplicación que realiza muchas asignaciones de memoria, recopilar todas las muestras en system.trace\_log puede generar una carga elevada.
</Warning>

También puede habilitarse para cada consulta mediante la configuración `jemalloc_collect_profile_samples_in_trace_log`.

<h3 id="example-analyzing-memory-usage-trace-log">
  Ejemplo: analizar el uso de memoria de una consulta
</h3>

Primero, ejecute una consulta con el perfilador de jemalloc habilitado y recopile las muestras en `system.trace_log`:

```sql theme={null}
SELECT *
FROM numbers(1000000)
ORDER BY number DESC
SETTINGS max_bytes_ratio_before_external_sort = 0
FORMAT `Null`
SETTINGS jemalloc_enable_profiler = 1, jemalloc_collect_profile_samples_in_trace_log = 1

Query id: 8678d8fe-62c5-48b8-b0cd-26851c62dd75

Ok.

0 rows in set. Elapsed: 0.009 sec. Processed 1.00 million rows, 8.00 MB (108.58 million rows/s., 868.61 MB/s.)
Peak memory usage: 12.65 MiB.
```

<Note>
  Si ClickHouse se inició con `jemalloc_enable_global_profiler`, no es necesario habilitar `jemalloc_enable_profiler`.
  Lo mismo ocurre con `jemalloc_collect_global_profile_samples_in_trace_log` y `jemalloc_collect_profile_samples_in_trace_log`.
</Note>

Vacía el `system.trace_log`:

```sql theme={null}
SYSTEM FLUSH LOGS trace_log
```

A continuación, consúltalo para obtener el uso acumulado de memoria a lo largo del tiempo:

```sql theme={null}
WITH per_bucket AS
(
    SELECT
        event_time_microseconds AS bucket_time,
        sum(size) AS bucket_sum
    FROM system.trace_log
    WHERE trace_type = 'JemallocSample'
      AND query_id = '8678d8fe-62c5-48b8-b0cd-26851c62dd75'
    GROUP BY bucket_time
)
SELECT
    bucket_time,
    sum(bucket_sum) OVER (
        ORDER BY bucket_time ASC
        ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
    ) AS cumulative_size,
    formatReadableSize(cumulative_size) AS cumulative_size_readable
FROM per_bucket
ORDER BY bucket_time
```

Encuentra el momento en que el uso de memoria fue más alto:

```sql theme={null}
SELECT
    argMax(bucket_time, cumulative_size),
    max(cumulative_size)
FROM
(
    WITH per_bucket AS
    (
        SELECT
            event_time_microseconds AS bucket_time,
            sum(size) AS bucket_sum
        FROM system.trace_log
        WHERE trace_type = 'JemallocSample'
          AND query_id = '8678d8fe-62c5-48b8-b0cd-26851c62dd75'
        GROUP BY bucket_time
    )
    SELECT
        bucket_time,
        sum(bucket_sum) OVER (
            ORDER BY bucket_time ASC
            ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
        ) AS cumulative_size,
        formatReadableSize(cumulative_size) AS cumulative_size_readable
    FROM per_bucket
    ORDER BY bucket_time
)
```

Con ese resultado, vea qué pilas de asignación estuvieron más activas en el punto máximo:

```sql theme={null}
SELECT
    concat(
        '\n',
        arrayStringConcat(
            arrayMap(
                (x, y) -> concat(x, ': ', y),
                arrayMap(x -> addressToLine(x), allocation_trace),
                arrayMap(x -> demangle(addressToSymbol(x)), allocation_trace)
            ),
            '\n'
        )
    ) AS symbolized_trace,
    sum(s) AS per_trace_sum
FROM
(
    SELECT
        ptr,
        sum(size) AS s,
        argMax(trace, event_time_microseconds) AS allocation_trace
    FROM system.trace_log
    WHERE trace_type = 'JemallocSample'
      AND query_id = '8678d8fe-62c5-48b8-b0cd-26851c62dd75'
      AND event_time_microseconds <= '2025-09-04 11:56:21.737139'
    GROUP BY ptr
    HAVING s > 0
)
GROUP BY ALL
ORDER BY per_trace_sum ASC
```

<h2 id="jemalloc-web-ui">
  UI web de jemalloc
</h2>

<Note>
  Esta sección se aplica a las versiones 26.2 o posteriores.
</Note>

ClickHouse proporciona una UI web integrada para ver las estadísticas de memoria de jemalloc en el endpoint HTTP `/jemalloc`.
Muestra métricas de memoria en tiempo real con gráficos, incluidas `allocated`, `active`, `resident` y `mapped`, así como estadísticas por arena y por bin.
También puedes obtener perfiles de heap globales y por consulta directamente desde la UI.

<Tabs>
  <Tab title="ClickHouse">
    ```text theme={null}
    http://localhost:8123/jemalloc
    ```

    La UI del servidor incluye todas las pestañas: Summary, Allocations, Arenas, Operations, Global Profiler, Query Profiler, Fragmentation y Raw Output.
  </Tab>

  <Tab title="Keeper">
    ```text theme={null}
    http://localhost:9182/jemalloc
    ```

    La UI de Keeper está disponible en el puerto de control HTTP. Este puerto está **deshabilitado de forma predeterminada** y debe habilitarse explícitamente configurando `keeper_server.http_control.port` en la configuración de Keeper:

    ```xml theme={null}
    <clickhouse>
        <keeper_server>
            <http_control>
                <port>9182</port>
            </http_control>
        </keeper_server>
    </clickhouse>
    ```

    Una vez habilitada, la UI ofrece las mismas visualizaciones que el servidor — Summary, Allocations, Arenas, Operations, Global Profiler y Raw Output — excepto las pestañas Query Profiler y Fragmentation, que requieren acceso SQL a las system tables.

    <Warning>
      **Seguridad**

      El puerto de control HTTP de Keeper no tiene autenticación a nivel de aplicación. A diferencia de la UI de jemalloc de ClickHouse Server — donde todas las consultas de datos pasan por el manejador HTTP de SQL y requieren credenciales de usuario/contraseña — los endpoints de la API REST de Keeper no requieren autenticación. Esto es coherente con otros endpoints de control HTTP de Keeper (commands, storage, dashboard).

      Restringe el acceso a este puerto mediante controles de red: vincula Keeper a localhost, usa reglas de firewall o colócalo detrás de un proxy inverso con autenticación. Si no se configura `listen_host`, Keeper escucha únicamente en localhost de forma predeterminada.
    </Warning>

    Keeper también expone endpoints de la API REST para acceso programático:

    * `GET /jemalloc/stats` — salida sin procesar de `malloc_stats_print`
    * `GET /jemalloc/status` — estado del perfilado en JSON (`prof_enabled`, `prof_active`, `thread_active_init`, `lg_sample`)
    * `GET /jemalloc/profile?format={collapsed|raw}` — hace flush de un perfil de heap con simbolización en el servidor; devuelve collapsed stacks aptas para renderizar flame graphs (predeterminado) o el dump sin procesar de jemalloc
  </Tab>
</Tabs>

<h2 id="fetching-heap-profiles-from-sql">
  Obtención de perfiles de heap desde SQL
</h2>

<Note>
  Esta sección se aplica a las versiones 26.2+.
</Note>

La tabla del sistema `system.jemalloc_profile_text` permite obtener y ver el perfil de heap actual de jemalloc directamente desde SQL, sin necesidad de herramientas externas ni de volcarlo antes a disco.

La tabla tiene una sola columna:

| Columna | Tipo | Descripción |
| - | - | - |
| `line` | String | Línea del perfil de heap de jemalloc simbolizado. |

Puede consultar la tabla directamente; no es necesario volcar antes un perfil de heap:

```sql theme={null}
SELECT * FROM system.jemalloc_profile_text
```

<h3 id="output-format">
  Formato de salida
</h3>

El formato de salida se controla mediante la configuración `jemalloc_profile_text_output_format`, que admite tres valores:

* `raw` — perfil de heap en bruto, tal como lo genera jemalloc.
* `symbolized` — formato compatible con jeprof con símbolos de función integrados. Como los símbolos ya están integrados, `jeprof` puede analizar la salida sin necesidad del binario de ClickHouse.
* `collapsed` (predeterminado) — collapsed stacks compatibles con FlameGraph, una pila por línea con el recuento de bytes.

Por ejemplo, para obtener el perfil en bruto:

```sql theme={null}
SELECT * FROM system.jemalloc_profile_text
SETTINGS jemalloc_profile_text_output_format = 'raw'
```

Para obtener una salida simbolizada:

```sql theme={null}
SELECT * FROM system.jemalloc_profile_text
SETTINGS jemalloc_profile_text_output_format = 'symbolized'
```

<h3 id="fetching-heap-profiles-settings">
  Ajustes adicionales
</h3>

* `jemalloc_profile_text_symbolize_with_inline` (Bool, valor predeterminado: `true`) — Indica si se deben incluir los frames inline al simbolizar. Desactivarlo acelera significativamente la simbolización, pero reduce la precisión, ya que las llamadas a funciones inline no aparecerán en los stacks. Solo afecta a los formatos `symbolized` y `collapsed`.
* `jemalloc_profile_text_collapsed_use_count` (Bool, valor predeterminado: `false`) — Al usar el formato `collapsed`, agrupa por número de asignaciones en lugar de por bytes.

<h3 id="example-flamegraph-from-sql">
  Ejemplo: generar un flame graph desde SQL
</h3>

Dado que el formato de salida predeterminado es `collapsed`, puedes redirigir la salida directamente a FlameGraph:

```sh theme={null}
clickhouse-client -q "SELECT * FROM system.jemalloc_profile_text" | flamegraph.pl --color=mem --title="Allocation Flame Graph" --width 2400 > result.svg
```

Para generar un flame graph según el recuento de asignaciones en lugar de por bytes:

```sh theme={null}
clickhouse-client -q "SELECT * FROM system.jemalloc_profile_text SETTINGS jemalloc_profile_text_collapsed_use_count = 1" | flamegraph.pl --color=mem --title="Allocation Count Flame Graph" --width 2400 > result.svg
```

<h2 id="analyzing-fragmentation-from-sql">
  Análisis de la fragmentación desde SQL
</h2>

<Note>
  Esta sección es aplicable a las versiones 26.9 y posteriores.
</Note>

jemalloc atiende las asignaciones pequeñas desde slabs: bloques de memoria de tamaño fijo divididos en regiones de una misma size class. Un slab solo se libera cuando todas sus regiones están libres. Si la mayoría de las asignaciones de una size class se liberan rápidamente, pero unas pocas perduran mucho tiempo, los slabs quedan retenidos con casi todas sus regiones libres. La memoria sigue residente, pero no está asignada. Eso es lo que aquí se entiende por fragmentación.

Dos system tables ayudan a averiguar de dónde proviene:

* [`system.jemalloc_arena_bins`](/es/reference/system-tables/jemalloc_bins) muestra cuánta memoria desperdicia cada size class en cada arena. `waste` son los bytes retenidos en slabs pero no utilizados por asignaciones vivas. `purpose` identifica las arenas dedicadas (`mergetree`, `jit`, `cache`); por diseño, estas contienen datos de larga duración, así que descártelas con `purpose = ''` cuando busque fragmentación inesperada. `system.jemalloc_bins` contiene los mismos datos agregados sobre todas las arenas.
* `system.jemalloc_sampled_allocations` enumera las asignaciones muestreadas que siguen vivas, una fila por sample: la traza inversa (`trace`), cuánto tiempo lleva viva (`age_ns`), el tamaño y la size class, y la arena. Leer la table provoca el flush de un nuevo perfil de heap.

Al unirlas por arena y size class se ve qué código asignó los objetos antiguos en las size classes que más desperdician.

Tenga en cuenta lo siguiente al leer los resultados:

* Solo los threads con el profiler activado generan samples (`jemalloc_enable_global_profiler` en la config o el SETTING `jemalloc_enable_profiler`).
* Cada fila representa aproximadamente `weight` asignaciones reales, y las asignaciones pequeñas se muestrean con poca frecuencia. Ajuste `jemalloc_profiler_sampling_rate` si las size classes que le interesan no tienen samples.
* Las asignaciones muestreadas no se almacenan en slabs, por lo que no contribuyen por sí mismas a `waste`. Solo indican qué código asigna en esa size class.
* Cada sample vivo cuesta dos páginas adicionales (128 KiB en builds con páginas de 64 KiB) hasta que la asignación se libera. Desactivar el profiler impide que se generen nuevos samples, pero no libera los existentes.

La siguiente consulta enumera las trazas inversas de las asignaciones con más de un minuto de antigüedad en las size classes que desperdician más de 1 MiB:

```sql theme={null}
WITH 60e9 AS min_age_ns
SELECT
    b.arena,
    b.size AS reg_size,
    b.waste AS class_waste,
    s.est_old_objects,
    s.stack
FROM system.jemalloc_arena_bins AS b
INNER JOIN
(
    SELECT
        arena,
        size_class,
        sum(weight) AS est_old_objects,
        arrayStringConcat(arrayMap(a -> demangle(addressToSymbol(a)), arrayReverse(trace)), ';') AS stack
    FROM system.jemalloc_sampled_allocations
    WHERE age_ns > min_age_ns
    GROUP BY arena, size_class, trace
) AS s ON s.size_class = b.index AND s.arena = b.arena
WHERE b.large = 0 AND b.purpose = '' AND b.waste > 1048576
ORDER BY b.waste DESC, s.est_old_objects DESC
SETTINGS allow_introspection_functions=1
```

<h3 id="example-fragmentation-flamegraph">
  Example: generación de un flame graph de fragmentación
</h3>

La misma consulta puede repartir el desperdicio de cada size class entre sus trazas inversas, en proporción a su número de asignaciones antiguas, e imprimir el resultado en el formato collapsed para `flamegraph.pl`. Las size classes con desperdicio pero sin samples suficientemente antiguos se agrupan bajo un frame `[unattributed]`, de modo que el total del flame graph equivale al desperdicio total. Lea `system.jemalloc_sampled_allocations` una sola vez por consulta: cada lectura hace flush de un nuevo profile, por lo que dos subqueries verían datos distintos.

```sql theme={null}
WITH 60e9 AS min_age_ns
SELECT format('{} {}',
    if(s.est_old_objects > 0, s.stack, format('[unattributed];arena_{}_class_{}', toString(b.arena), toString(b.size))),
    toString(toUInt64(if(s.est_old_objects > 0, b.waste * s.est_old_objects / sum(s.est_old_objects) OVER (PARTITION BY b.arena, b.index), b.waste))))
FROM system.jemalloc_arena_bins AS b
LEFT JOIN
(
    SELECT
        arena,
        size_class,
        sum(weight) AS est_old_objects,
        arrayStringConcat(arrayMap(a -> demangle(addressToSymbol(a)), arrayReverse(trace)), ';') AS stack
    FROM system.jemalloc_sampled_allocations
    WHERE age_ns > min_age_ns
    GROUP BY arena, size_class, trace
) AS s ON s.size_class = b.index AND s.arena = b.arena
WHERE b.large = 0 AND b.purpose = '' AND b.waste > 0
SETTINGS allow_introspection_functions=1
```

```sh theme={null}
clickhouse-client -q "..." | flamegraph.pl --color=mem --title="Fragmentation Flame Graph" --width 2400 > result.svg
```

<h2 id="flushing-heap-profiles">
  Volcado de perfiles de heap a disco
</h2>

Si necesitas guardar perfiles de heap como archivos para analizarlos sin conexión con `jeprof`, puedes volcarlos a disco.

De forma predeterminada, el archivo del perfil de heap se generará en `/tmp/jemalloc_clickhouse._pid_._seqnum_.heap`, donde `_pid_` es el PID de ClickHouse y `_seqnum_` es el número de secuencia global del perfil de heap actual.
Para Keeper, el archivo predeterminado es `/tmp/jemalloc_keeper._pid_._seqnum_.heap` y sigue las mismas reglas.

Para volcar el perfil actual:

<Tabs>
  <Tab title="ClickHouse">
    ```sql theme={null}
    SYSTEM JEMALLOC FLUSH PROFILE
    ```

    Devolverá la ubicación del perfil volcado.
  </Tab>

  <Tab title="Keeper">
    ```sh theme={null}
    echo jmfp | nc localhost 9181
    ```
  </Tab>
</Tabs>

Se puede definir una ubicación diferente añadiendo la opción `prof_prefix` a la variable de entorno `MALLOC_CONF`.
Por ejemplo, si quieres generar perfiles en la carpeta `/data`, donde el prefijo del nombre de archivo será `my_current_profile`, puedes ejecutar ClickHouse/Keeper con la siguiente variable de entorno:

```sh theme={null}
MALLOC_CONF=prof_prefix:/data/my_current_profile
```

El archivo generado se añadirá al prefijo, al PID y al número de secuencia.

<h2 id="analyzing-heap-profile-files-with-jeprof">
  Análisis de archivos de perfiles de heap con `jeprof`
</h2>

Después de volcar los perfiles de heap en disco, se pueden analizar con la herramienta de `jemalloc` llamada [jeprof](https://github.com/jemalloc/jemalloc/blob/dev/bin/jeprof.in). Se puede instalar de varias maneras:

* Usando el gestor de paquetes del sistema
* Clonando el [repositorio de jemalloc](https://github.com/jemalloc/jemalloc) y ejecutando `autogen.sh` desde la carpeta raíz. Esto le proporcionará el script `jeprof` dentro de la carpeta `bin`

Hay varios formatos de salida disponibles. Ejecute `jeprof --help` para ver la lista completa de opciones.

<h3 id="symbolized-heap-profiles">
  Perfiles de heap simbolizados
</h3>

A partir de la versión 26.1+, ClickHouse genera automáticamente perfiles de heap simbolizados al ejecutar `SYSTEM JEMALLOC FLUSH PROFILE`.
El perfil simbolizado (con la extensión `.symbolized`) contiene símbolos de función integrados y puede analizarse con `jeprof` sin necesidad del binario de ClickHouse.

Por ejemplo, cuando ejecutas:

```sql theme={null}
SYSTEM JEMALLOC FLUSH PROFILE
```

ClickHouse devolverá la ruta al perfil simbolizado (p. ej., `/tmp/jemalloc_clickhouse.12345.0.heap.symbolized`).

Luego puedes analizarlo directamente con `jeprof`:

```sh theme={null}
jeprof /tmp/jemalloc_clickhouse.12345.0.heap.symbolized --output_format [ > output_file]
```

<Note>
  **No se requiere el binario**: Al usar perfiles simbolizados (archivos `.symbolized`), no necesitas proporcionar a `jeprof` la ruta del binario de ClickHouse. Esto facilita mucho el análisis de perfiles en distintas máquinas o después de actualizar el binario.
</Note>

Si tienes un heap profile no simbolizado más antiguo y todavía tienes acceso al binario de ClickHouse, puedes usar el enfoque tradicional:

```sh theme={null}
jeprof path/to/clickhouse path/to/heap/profile --output_format [ > output_file]
```

<Note>
  Para perfiles no simbolizados, `jeprof` usa `addr2line` para generar stacktraces, lo que puede ser bastante lento.
  Si es así, se recomienda instalar una [implementación alternativa](https://github.com/gimli-rs/addr2line) de la herramienta.

  ```bash theme={null}
  git clone https://github.com/gimli-rs/addr2line.git --depth=1 --branch=0.23.0
  cd addr2line
  cargo build --features bin --release
  cp ./target/release/addr2line path/to/current/addr2line
  ```

  Como alternativa, `llvm-addr2line` funciona igual de bien (pero tenga en cuenta que `llvm-objdump` no es compatible con `jeprof`).

  Y después úselo así: `jeprof --tools addr2line:/usr/bin/llvm-addr2line,nm:/usr/bin/llvm-nm,objdump:/usr/bin/objdump,c++filt:/usr/bin/llvm-cxxfilt`
</Note>

Al comparar dos perfiles, puede usar el argumento `--base`:

```sh theme={null}
jeprof --base /path/to/first.heap.symbolized /path/to/second.heap.symbolized --output_format [ > output_file]
```

<h3 id="examples">
  Ejemplos
</h3>

Con perfiles simbolizados (recomendado):

* Genere un archivo de texto con cada procedimiento en una línea:

```sh theme={null}
jeprof /tmp/jemalloc_clickhouse.12345.0.heap.symbolized --text > result.txt
```

* Genera un archivo PDF con el grafo de llamadas:

```sh theme={null}
jeprof /tmp/jemalloc_clickhouse.12345.0.heap.symbolized --pdf > result.pdf
```

Uso de perfiles sin simbolizar (requiere el binario):

* Genere un archivo de texto con un procedimiento por línea:

```sh theme={null}
jeprof /path/to/clickhouse /tmp/jemalloc_clickhouse.12345.0.heap --text > result.txt
```

* Genera un archivo PDF con un grafo de llamadas:

```sh theme={null}
jeprof /path/to/clickhouse /tmp/jemalloc_clickhouse.12345.0.heap --pdf > result.pdf
```

<h3 id="generating-flame-graph">
  Generar un flame graph
</h3>

`jeprof` permite generar collapsed stacks para crear flame graphs.

Debe usar el argumento `--collapsed`:

```sh theme={null}
jeprof /tmp/jemalloc_clickhouse.12345.0.heap.symbolized --collapsed > result.collapsed
```

O con un perfil sin simbolizar:

```sh theme={null}
jeprof /path/to/clickhouse /tmp/jemalloc_clickhouse.12345.0.heap --collapsed > result.collapsed
```

Después, puedes usar muchas herramientas distintas para visualizar collapsed stacks.

La más popular es [FlameGraph](https://github.com/brendangregg/FlameGraph), que incluye un script llamado `flamegraph.pl`:

```sh theme={null}
cat result.collapsed | /path/to/FlameGraph/flamegraph.pl --color=mem --title="Allocation Flame Graph" --width 2400 > result.svg
```

Otra herramienta interesante es [speedscope](https://www.speedscope.app/), que te permite analizar los stacks recopilados de forma más interactiva.

<h2 id="additional-options-for-profiler">
  Opciones adicionales para el perfilador
</h2>

`jemalloc` ofrece muchas opciones relacionadas con el perfilador. Se pueden controlar modificando la variable de entorno `MALLOC_CONF`.
Por ejemplo, el intervalo entre muestras de asignación puede controlarse con `lg_prof_sample`.
Si desea volcar el perfil de heap cada N bytes, puede habilitarlo con `lg_prof_interval`.

Se recomienda consultar la [página de referencia](https://jemalloc.net/jemalloc.3.html) de `jemalloc` para ver la lista completa de opciones.

<h2 id="other-resources">
  Otros recursos
</h2>

ClickHouse/Keeper exponen métricas relacionadas con `jemalloc` de muchas formas distintas.

<Warning>
  **Advertencia**

  Es importante tener en cuenta que ninguna de estas métricas está sincronizada con las demás y que los valores pueden diferir.
</Warning>

<h3 id="system-table-asynchronous_metrics">
  Tabla del sistema `asynchronous_metrics`
</h3>

```sql theme={null}
SELECT *
FROM system.asynchronous_metrics
WHERE metric LIKE '%jemalloc%'
FORMAT Vertical
```

[Referencia](/es/reference/system-tables/asynchronous_metrics)

<h3 id="system-table-jemalloc_bins">
  Tabla del sistema `jemalloc_bins`
</h3>

Contiene información sobre las asignaciones de memoria realizadas mediante el asignador jemalloc en distintas clases de tamaño (bins), agregadas de todas las arenas.

[Referencia](/es/reference/system-tables/jemalloc_bins)

<h3 id="system-table-jemalloc_stats">
  Tabla del sistema `jemalloc_stats` (26.2+)
</h3>

Devuelve la salida completa de `malloc_stats_print()` en una sola cadena. Equivale al comando `SYSTEM JEMALLOC STATS`.

```sql theme={null}
SELECT * FROM system.jemalloc_stats
```

<h3 id="prometheus">
  Prometheus
</h3>

Todas las métricas relacionadas con `jemalloc` de `asynchronous_metrics` también están expuestas a través del endpoint de Prometheus tanto en ClickHouse como en Keeper.

[Referencia](/es/reference/settings/server-settings/settings/other#prometheus)

<h3 id="jmst-4lw-command-in-keeper">
  Comando 4LW `jmst` de Keeper
</h3>

Keeper admite el comando 4LW `jmst`, que devuelve [estadísticas básicas del asignador de memoria](https://github.com/jemalloc/jemalloc/wiki/Use-Case%3A-Basic-Allocator-Statistics):

```sh theme={null}
echo jmst | nc localhost 9181
```
