> ## Documentation Index
> Fetch the complete documentation index at: https://docs.appsignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Global VM Lock

export const VersionRequirements = ({versions = []}) => {
  if (!Array.isArray(versions) || versions.length === 0) {
    return null;
  }
  const boundaries = {
    upper: " or lower",
    exact: "",
    lower: " or higher"
  };
  const containerStyle = {
    marginTop: "0.5rem",
    marginBottom: "1.5rem"
  };
  const lineStyle = {
    display: "block",
    margin: "0 0 0.35rem 0",
    fontSize: "0.875rem",
    lineHeight: "1.4"
  };
  const pillBaseStyle = {
    display: "inline-block",
    padding: "0.1em 0.4em",
    borderRadius: "0.25rem",
    border: "1px solid",
    fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
    fontSize: "0.85em",
    fontWeight: 500
  };
  const pillColors = {
    "AppSignal for Elixir": {
      background: "#f3e8ff",
      borderColor: "#e9d5ff",
      color: "#9333ea"
    },
    "AppSignal for Front-end": {
      background: "#fef9c3",
      borderColor: "#fde68a",
      color: "#ca8a04"
    },
    "AppSignal for Go": {
      background: "#ccfbf1",
      borderColor: "#99f6e4",
      color: "#0d9488"
    },
    "AppSignal for JavaScript": {
      background: "#fef9c3",
      borderColor: "#fde68a",
      color: "#ca8a04"
    },
    "AppSignal for Node.js": {
      background: "#dcfce7",
      borderColor: "#bbf7d0",
      color: "#16a34a"
    },
    "AppSignal for Python": {
      background: "#dbeafe",
      borderColor: "#bfdbfe",
      color: "#2563eb"
    },
    "AppSignal for Ruby": {
      background: "#fee2e2",
      borderColor: "#fecaca",
      color: "#dc2626"
    },
    "AppSignal for Rust": {
      background: "#ffedd5",
      borderColor: "#fed7aa",
      color: "#ea580c"
    }
  };
  const defaultPillColor = {
    background: "#f4f4f5",
    borderColor: "#e4e4e7",
    color: "#52525b"
  };
  const getPillStyle = name => ({
    ...pillBaseStyle,
    ...pillColors[name] || defaultPillColor
  });
  const getBoundText = bound => {
    return boundaries[bound] || boundaries.lower;
  };
  return <div style={containerStyle}>
      {versions.map((v, i) => <p key={`${v.name}-${v.version}-${v.bound || "lower"}-${i}`} style={lineStyle}>
          This feature requires{" "}
          <code style={getPillStyle(v.name)}>{v.name}</code> version {v.version}
          {getBoundText(v.bound)}.
        </p>)}
    </div>;
};

<VersionRequirements
  versions={[
{ name: "AppSignal for Ruby", version: "3.3.9" },
{ name: "Ruby", version: "3.2" },
{ name: "gvltools", version: "0.2" }
]}
/>

A Ruby VM (Máquina Virtual) agenda threads Ruby para execução. Em qualquer momento, apenas uma thread por vez pode estar ativa e interagir com o estado da Ruby VM.

O mecanismo pelo qual o interpretador Ruby garante isso é o Global VM Lock (GVL).

A troca entre threads tem uma sobrecarga própria. As métricas sobre o Global VM Lock permitem que você veja o tempo que uma thread passa esperando sua vez de executar e o número de threads aguardando execução em um determinado momento. Essas métricas podem fornecer insights úteis para entender problemas de desempenho em sua aplicação.

Quando o AppSignal detecta métricas do Global VM Lock, ele criará um [Magic Dashboard](#magic-dashboard), permitindo que você monitore métricas principais visualmente.

## Instalação

<Warning>
  A biblioteca `gvltools` é compatível apenas com o interpretador Ruby oficial.
  JRuby não é suportado.
</Warning>

Para que o AppSignal possa obter as métricas do Global VM Lock, você deve adicionar a biblioteca `gvltools` ao seu projeto:

<CodeGroup>
  ```shell Shell theme={null}
  bundle add gvltools
  ```
</CodeGroup>

Uma vez instalada, a integração do AppSignal coletará automaticamente as métricas do Global VM Lock a cada minuto.

## Magic dashboards

Os magic dashboards aparecerão na seção [Dashboard](https://appsignal.com/redirect-to/app?to=dashboard) do AppSignal.

<img src="https://mintcdn.com/appsignal-715f5a51/4TRZP0Sq9Zq7PAPW/assets/images/screenshots/ruby/integrations/global-vm-lock/magic-dashboard.png?fit=max&auto=format&n=4TRZP0Sq9Zq7PAPW&q=85&s=005c856a34ea7513ae781ce685cb6c45" alt="Criação do magic dashboard do Ruby GVL" width="2548" height="1430" data-path="assets/images/screenshots/ruby/integrations/global-vm-lock/magic-dashboard.png" />

O magic dashboard do Global VM Lock tem os seguintes gráficos:

| Gráfico                                   | Métrica               |
| ----------------------------------------- | --------------------- |
| [Global timer](#global-timer-graph)       | `gvl_global_timer`    |
| [Waiting threads](#waiting-threads-graph) | `gvl_waiting_threads` |

O AppSignal reporta as seguintes tags para as métricas do Global VM Lock:

| Nome           | Descrição                                          |
| -------------- | -------------------------------------------------- |
| `hostname`     | O nome do host do qual a métrica foi reportada     |
| `process_id`   | O ID do processo do qual a métrica foi reportada   |
| `process_name` | O nome do processo do qual a métrica foi reportada |

<Tip>
  As tags `process_id` e `process_name` são reportadas apenas quando se usa
  o AppSignal for Ruby versão 3.9.3 ou mais nova.
</Tip>

<img src="https://mintcdn.com/appsignal-715f5a51/4TRZP0Sq9Zq7PAPW/assets/images/screenshots/ruby/integrations/global-vm-lock/dashboard-graphs.png?fit=max&auto=format&n=4TRZP0Sq9Zq7PAPW&q=85&s=7adb9334fbf51a1ab2d6e28aad0c5d3f" alt="Magic dashboard do Ruby GVL" width="2200" height="872" data-path="assets/images/screenshots/ruby/integrations/global-vm-lock/dashboard-graphs.png" />

### Gráfico Global timer

O gráfico global timer mostra o tempo que as threads passaram esperando para serem retomadas durante o último minuto, ou seja, esperando que seu código fosse executado novamente.

#### Configurando a medição do global timer

A medição do global timer tem uma sobrecarga de desempenho estimada de 5%.

Para evitar impactos negativos no desempenho da sua aplicação, você pode querer desabilitar `gvl_global_timer` por padrão e habilitá-lo quando necessário para requisições específicas ou jobs intensivos em threads.

Para desabilitar esta métrica no momento do start, defina [a opção de configuração `enable_gvl_global_timer`](/ruby/configuration/options#option-enable_gvl_global_timer) como `false`.

Então, você pode usar a biblioteca `gvltools` para habilitar e desabilitar a medição do global timer sem precisar reiniciar sua aplicação:

<CodeGroup>
  ```ruby Ruby theme={null}
  require "gvltools"

  GVLTools::GlobalTimer.enable

  # algum código que usa threads ...

  GVLTools::GlobalTimer.disable
  ```
</CodeGroup>

### Gráfico Waiting threads

O gráfico waiting threads mostra o número de threads aguardando para serem retomadas em um determinado momento. O gráfico não inclui threads que não estão prontas para serem retomadas, como threads que estão em sleep ou aguardando um evento de I/O.

Para desabilitar esta métrica, você pode definir [a opção de configuração `enable_gvl_waiting_threads`](/ruby/configuration/options#option-enable_gvl_waiting_threads) como `false`.
