Quando Executamos Um Programa O Mesmo Permanece Na
O que acontece com um programa depois de ser executado
Quando executamos um programa o mesmo permanece na memória RAM como um processo ativo até que seja concluído ou finalizado. Essa é a parte óbvia. O que as pessoas não entendem é que existem vários estágios entre o momento em que você clica no ícone e o momento em que ele simplesmente desaparece da tela. Um programa não roda como uma unidade sólida. Ele se divide em threads. O processo principal carrega o binário, aloca o espaço de endereçamento, abre os descritores de arquivo necessários, e aí vêm as threads. Uma delas cuida da interface gráfica, outra processa dados em segundo plano, outra gerencia a rede. Tudo isso ocupa memória. E cada thread tem seu próprio stack separado, geralmente 1 a 8 MB por padrão em sistemas modernos. Se você já abriu o monitor de atividades no Windows e viu um único programa usando 500 MB de RAM, provavelmente é porque tinha múltiplas threads rodando junto com o processo principal. Isso não é exagero. É o comportamento normal.
O ciclo de vida real do processo
O processo nasce quando o sistema operacional recebe a chamada exec. O kernel reserva um PCB (Process Control Block), aloca espaço na heap, mapeia os segmentos do arquivo executável na memória virtual. Na prática, isso leva alguns milissegundos. Dependendo do tamanho do binário e da quantidade de bibliotecas compartilhadas que precisam ser carregadas, pode demorar até 2 ou 3 segundos em programas grandes como editores de vídeo ou IDEs. Enquanto roda, o processo acessa memória, lê arquivos, faz requisições de rede. O scheduler do kernel decide quantos ciclos de CPU ele recebe a cada tick. Se o programa for intensivo em CPU, ele vai consumir mais tempo de processador. Se for mais IO-bound, vai passar muito tempo esperando. Aqui está o ponto que quase todo mundo ignora: quando o programa termina, ele não some imediatamente da memória. O processo entra no estado zumbi (zombie) no Linux e Unix, ou no estado terminated no Windows, aguardando que o processo pai faça uma chamada wait() para coletar o status de saída. Esse estágio pode durar de alguns milissegundos a vários segundos, dependendo de como o programa foi escrito.
Eu tive um caso recente com um serviço em Python que deveria terminar rápido mas ficava como zombie por cerca de 40 segundos. O problema era que o processo pai estava ocupado processando outro evento e só chamava wait() quando tinha folga. A solução foi implementar um handler para SIGCHLD que chama waitpid() de forma não-bloqueante assim que qualquer filho termina. Resolveu em segundos.

O que acontece com a memória após o término
Depois que o processo pai coleta o status, o kernel libera o PCB e todas as páginas de memória alocadas. Mas aqui tem outra coisa que gera confusão. O sistema operacional mantém uma cópia dos binários e bibliotecas compartilhadas em cache na memória, mesmo depois que o processo que os usou já morreu. Se você rodar outro programa que use as mesmas bibliotecas, ele carrega muito mais rápido porque os dados já estão na RAM. Isso é chamado de page cache ou file cache, dependendo do sistema. No Linux, você consegue ver quanto disso está sendo usado com o comando free ou analisando /proc/meminfo. As colunas Buffers e Cached mostram exatamente essa memória "emprestada" ao sistema de arquivos. Em máquinas com pouca RAM, esse comportamento pode causar problemas. Se vários programas grandes forem abertos e fechados em sequência, o cache pode crescer demais e o sistema começa a fazer swap. Eu vi um servidor de desenvolvimento com 4 GB de RAM onde o cache de página chegava a 2,5 GB depois de rodar Docker,Node e um banco local. O Swap entrava em ação e tudo ficava lento até o usuário abrir uma aba nova no navegador.
Programas que não terminam de verdade
Alguns programas são projetados para permanecer ativos mesmo após a interface visual ser fechada. Serviços de background, demon, servidores web, aplicativos tray. No Windows eles aparecem como processos no Gerenciador de Tarefas mesmo sem janela aberta. No Linux, são processos que desanexam do terminal e continuam rodando. Isso é intencional e funcional. Problemas começam quando esses processos não são bem gerenciados. Vazamento de memória é o mais comum. Um serviço que cresce 5 MB por hora parece inofensivo no início. Depois de 30 dias, você tem 3,6 GB de RAM consumidos por um processo que deveria usar no máximo 200 MB. Eu corrigi isso em um projeto configurando limites de memória no systemd com MemoryMax e MemoryHigh, e programando um restart periódico via Timer unit. O processo nunca chegava a estourar o limite.
Como verificar o que está rodando
No Linux, o comando ps aux mostra todos os processos com PID, uso de CPU, uso de memória e comando executado. O top atualiza em tempo real. O htop é uma versão interativa que facilita a identificação de processos que consomem recursos desproporcionalmente. No Windows, o Gerenciador de Tarefas cumpre o mesmo papel, mas a aba "Detalhes" é mais próxima do ps do Linux em termos de informação disponível. Se você quer algo mais preciso, o comando pstree no Linux mostra a árvore de processos, ou seja, qual processo iniciou cada um dos outros. Isso é útil para entender quem é o pai de um processo zombie ou quem controla um daemon.

Limitações e armadilhas conhecidas
O modelo de processos do sistema operacional não é perfeito. Um deles é o problema dos orfãos: se o processo pai morre sem coletar os filhos, eles ficam órfãos e são adotados pelo init ou systemd. Isso pode parecer inofensivo, mas na prática causa acúmulo de processos que ninguém acompanha. Outro problema é o fork bomb, onde um programa cria processos em velocidade exponencial até saturar a tabela de processos do kernel. Também vale mencionar que a memória mostrada pelos monitores de sistema nem sempre reflete a memória física real. Em Linux, o comando RSS (Resident Set Size) mostra quanto do processo está efetivamente na RAM, enquanto o VSZ (Virtual Size) inclui toda a memória mapeada, mesmo que grande parte nunca tenha sido acessada. Um programa pode mostrar 2 GB de VSZ mas usar apenas 150 MB de RSS. Confundir esses dois números leva a diagnósticos errados sobre consumo de memória. Se o objetivo é realmente controlar quanto memória um processo pode usar, a solução mais confiável é usar namespaces e cgroups no Linux. Eles oferecem controle granular de CPU, memória, I/O e rede. Ferramentas como Docker e systemd já aplicam isso por padrão, mas se você estiver executando processos diretamente no sistema, precisa configurar manualmente.
Galeria
-
PPT - Execução de Programas PowerPoint Presentation, free download - ID ... -
PPT - Execução de Programas PowerPoint Presentation, free download - ID ... -
PPT - Computadores e Linguagens de Programação PowerPoint Presentation ...