Faz muito tempo desde que eu aprendi essas coisas, mas aqui vai.
Quando um sistema operacional inicia um processo, ele atribui páginas a partir da tabela de memória virtual. O sistema operacional é responsável por manter um mapa da tabela de memória virtual para a memória real ou para o espaço de troca no disco. Quando um processo é morto, o sistema operacional não pára de fornecer ciclos de CPU. Ele faz alguns itens de limpeza, um dos quais é para marcar todas as suas páginas de memória como livres. Isso permite que eles sejam reutilizados por outros aplicativos. O sistema operacional provavelmente também limpará todos os identificadores de recursos que o processo tinha, fechando arquivos, conexões de rede, canais de processo a processo e assim por diante. Este processo está totalmente sob o controle do sistema operacional, e essas etapas serão executadas independentemente de como o processo tenha morrido.
Tenha em mente que tudo isso se aplica aos processos do sistema operacional. Se você tiver algum tipo de máquina virtual e estiver executando vários processos virtuais de uma só vez, a VM será responsável por decidir como alocar e desalocá-los. No SO, no entanto, ainda parece um processo. Portanto, neste caso, se você tem uma VM que executa vários processos e mata um deles na VM, provavelmente não recuperará imediatamente a memória no sistema operacional host. Mas você vai recuperá-lo na VM. Se você matar a VM dentro do sistema operacional, no entanto, o sistema operacional matará a VM (que indiretamente mata os processos da VM) e recuperará toda a memória (que não precisará passar por um coletor de lixo, free () , excluir ou qualquer outra coisa).
Altamente especulativo:
Se o .NET for executado como uma máquina virtual com mais de um aplicativo .NET na mesma VM, o .NET poderá manter a memória que ainda não é GCd até que execute o GC, e o Windows pensaria que O .NET está usando mais do que realmente é. (E, se o MS fosse realmente liso, o Windows poderia informar o .NET para o GC em situações de memória apertada, mas quase não há sentido para isso, porque é para isso que serve o espaço de troca de disco.)
Se o .NET funcionasse dessa forma, o sistema operacional ainda pensaria nele como um processo para fins de SO, que toma a responsabilidade de decidir o que manter e o que descartar, e normalmente não é problema do Windows informar um processo. que precisa começar a desalocar a memória. Nesse ponto, é possível que o MS crie uma API especial apenas para .NET, para que os processos .NET pareçam processos do Windows, exceto que eles não são, e é por isso que as pessoas podem pensar que a memória do processo não está sendo desalocada. É realmente; é só que você está olhando para o processo errado.
Eu não sei o suficiente sobre o .NET para dizer que ele realmente funciona dessa maneira; o Java VM certamente não faz.
Fim da especulação.
EDITAR: No que diz respeito a matar um processo que está sendo ruim para gerenciamento de memória, isso requer múltiplos processos para alocar fora do mesmo pool (ie eles são mais como threads que processos reais) e para a memória para não ser liberada após o processo ser morto. Isso quase exigiria um sistema cooperativo de multitarefa, porque a memória virtual e a multitarefa preventiva eram, em minha opinião, normalmente implementadas juntas (a VM possibilitando isolar processos uns dos outros e impedi-los de pisar na memória um do outro). Ter memória virtual torna trivial a limpeza após um processo no nível do sistema operacional; basta mover todas as páginas do pool do processo para o pool gratuito.