Pular para o conteúdo principal

Recursos e limites da JVM

Um NNS em Java pede CPU e memória no nnp/placement.yaml; o Module Manager injeta esses valores no chart. O padrão do SDK:

resources: {requests: {cpu: 250m, memory: 512Mi}, limits: {cpu: "1", memory: 768Mi}}
replicas: 2
requestlimit
CPU250m1
memória512Mi768Mi

Nunca use requests: none em produção, e não peça recursos absurdos "por segurança": o teto por classe de placement é do target, e um pedido irreal não agenda.

O que os números significam​

Medido no laboratório com um NNS em JVM (1 CPU, 768 Mi de limite):

grandezavalor
RSS em regime180–251 Mi
pico observado288 Mi
request de memória512 Mi — deixa o pico esperado longe do gatilho de memória
limite de memória768 Mi

O RSS fica bem abaixo do limite de propósito: o limite não é o heap. O processo soma heap, metaspace, code cache, thread stacks, buffers de I/O direto, o próprio JRE e o hsperfdata. O que manda no dimensionamento é o memory calculator do buildpack.

O memory calculator e o BPL_JVM_THREAD_COUNT​

O buildpack BellSoft Liberica calcula a memória da JVM a partir do limite do container e do número de threads. O padrão dele conta 250 threads, e com esse número o cálculo não parte abaixo de ~640 Mi.

O chart fixa um valor explícito:

env:
# Imagem JVM (D108): o memory calculator do Paketo conta 250 threads por padrão e não
# parte abaixo de ~640 Mi; com 100 cabe com folga em 768 Mi.
- {name: BPL_JVM_THREAD_COUNT, value: "100"}

Consequências práticas:

  • Mudar o limite de memória sem revisar esse número muda o heap calculado. O valor é literal e fechado por contrato: é a exceção declarada da regra chart_runtime_env — outras variáveis de ambiente do runtime não são aceitas no chart.
  • Mudar o número de threads do serviço muda o valor certo aqui. O SDK usa threads virtuais e um pool limitado; 100 cobre os listeners, o pool e as tarefas periódicas de um módulo comum. Um serviço com trabalho de fundo pesado deve subir isso — e medir.
  • Heap maior não é a resposta para OOM. Com heap fixo de 256 Mi já houve OOM sob carga; o caminho foi ajustar o cálculo, não o heap.

O mesmo BPL_JVM_THREAD_COUNT: "100" aparece no Job de migração, para a contabilidade da JVM ser a mesma nos dois processos.

Como escolher os seus valores​

  1. Comece do padrão (250m/512Mi → 1/768Mi).
  2. Rode com carga representativa e observe o RSS e o throttling de CPU.
  3. Se a memória apertar, ajuste primeiro BPL_JVM_THREAD_COUNT (e meça de novo).
  4. Suba o limite apenas com a medida na mão — e lembre que o número do memory calculator acompanha.
  5. Registre a medida: é o que permite a quem vier depois não repensar tudo.

replicas é também o mínimo quando há autoscaling (veja Escala automática). Um módulo cujo trabalho é limitado por banco ou por serviço externo não ganha vazão com réplicas a mais: as tarefas periódicas rodam em toda réplica da release ativa.

Onde conferir​

./nnconsolew descriptors validate --dir nnp # o placement é válido
./nnconsolew chart check --values nns/helm/testdata/injected-values.yaml --namespace <ns> \
--runtime jvm --runtime-user 1002 nns/helm/chart # os recursos chegam ao manifesto

O nnp plan também mostra o efeito do placement no plano de deploy, antes de qualquer upload:

./nnconsolew nnp plan dist/<módulo>-<versão>.nnp --targets <targets> --target <id> --all-capabilities