O que e onde estão a pilha e a pilha?

Livros em linguagens de programação explicam que tipos de valor são criados na pilha e tipos de referência são criados na pilha , sem explicar o que são essas duas coisas. Eu não li uma explicação clara para isso. Eu entendo o que é uma pilha. Mas

  • onde e o que eles são (fisicamente na memória real do computador)?
  • Até que ponto eles são controlados pelo sistema operacional ou idioma?
  • Qual é o volume deles?
  • O que determina o tamanho de cada um deles?
  • O que faz mais rápido?
7380
17 сент. set mattshane 17 de setembro 2008-09-17 07:18 '08 at 7:18 am 2008-09-17 07:18
@ 25 respostas

Uma pilha é uma memória reservada como espaço de rascunho para um encadeamento de execução. Quando uma função é chamada, o bloco é reservado no topo da pilha para variáveis ​​locais e algumas credenciais. Quando esta função retorna, o bloco não é usado e pode ser usado na próxima vez que a função for chamada. A pilha é sempre reservada na ordem de LIFO (a última na primeira ordem); o bloco reservado mais recente é sempre o próximo bloco a ser liberado. Isso facilita o rastreamento da pilha; liberar um bloco da pilha nada mais é do que um único ajuste de ponteiro.

Um heap é uma memória alocada para alocação dinâmica. Ao contrário da pilha, não há um modelo forçado para alocar e liberar blocos de um heap; Você pode selecionar um bloco a qualquer momento e liberá-lo a qualquer momento. Isso torna muito difícil controlar quais partes do heap são distribuídas ou liberadas a qualquer momento; Há muitos distribuidores cum personalizados para ajustar o desempenho do heap para diferentes padrões de uso.

Cada encadeamento recebe uma pilha, enquanto que, para um aplicativo, apenas um heap é normalmente usado (embora não seja incomum ter vários heaps para diferentes tipos de posicionamento).

Para responder suas perguntas diretamente:

Até que ponto eles são controlados pelo sistema operacional ou idioma?

O SO aloca uma pilha para cada encadeamento no nível do sistema ao criar um encadeamento. Normalmente, o sistema operacional é chamado pelo ambiente de execução de linguagem para alocar um heap para um aplicativo.

Qual é o volume deles?

A pilha é anexada ao encadeamento, portanto, quando o encadeamento sai da pilha, ele é corrigido. Um heap geralmente é alocado quando o aplicativo é iniciado no tempo de execução e retorna depois que o aplicativo (processo técnico) é encerrado.

O que determina o tamanho de cada um deles?

O tamanho da pilha é definido ao criar um segmento. O tamanho de heap é definido quando o aplicativo é iniciado, mas pode aumentar conforme necessário (o alocador solicita mais memória do sistema operacional).

O que faz mais rápido?

A pilha é mais rápida porque o padrão de acesso torna trivial alocar e liberar memória dela (o ponteiro / número inteiro simplesmente aumenta ou diminui), e o heap tem demonstrações financeiras muito mais complicadas relacionadas à alocação ou liberação. Além disso, cada byte na pilha é frequentemente reutilizado, o que significa que ele tende a ser exibido no cache do processador, o que o torna muito rápido. Outro impacto no desempenho do heap é que o heap, que é principalmente um recurso global, deve ser tipicamente multiencadeado, ou seja, Cada distribuição e release deve ser - como regra, sincronizada com "todas" outras chamadas de heap no programa.

Demonstração clara: 2019

5436
17 сент. A resposta é dada Jeff Hill 17 de setembro. 2008-09-17 07:52 '08 at 7:52 am 2008-09-17 07:52

Pilha

  • Salvo na RAM do computador, como um grupo.
  • Variáveis ​​criadas na pilha saem do escopo e são automaticamente liberadas.
  • Muito mais rápido para alocar comparado às variáveis ​​no heap.
  • Implementado com estrutura de dados de pilha real.
  • Salva dados locais, retorna endereços usados ​​para passar parâmetros.
  • Pode ter um estouro de pilha quando muito da pilha é usada (principalmente de recursão infinita ou muito profunda, distribuições muito grandes).
  • Dados criados na pilha podem ser usados ​​sem ponteiros.
  • Você usaria a pilha se soubesse exatamente quantos dados precisa alocar antes de compilar, e não é muito grande.
  • Normalmente, o tamanho máximo já é determinado quando o programa é iniciado.

Heap:

border=0
  • Armazenado na memória do computador da mesma forma que a pilha.
  • Em C ++, as variáveis ​​no heap devem ser destruídas manualmente e nunca saírem do escopo. Os dados são liberados com delete , delete[] ou free .
  • É mais lento alocar comparado às variáveis ​​na pilha.
  • Usado sob demanda para alocar um bloco de dados para uso pelo programa.
  • Pode ter fragmentação quando há muitas alocações e isenções.
  • Em C ++ ou C, os dados criados no heap serão indicados por ponteiros e alocados para new ou malloc respectivamente.
  • Pode haver uma falha na distribuição se for necessário muito buffer.
  • Você usaria um monte se não souber exatamente quantos dados precisa em tempo de execução ou se precisar alocar muitos dados.
  • Responsável pelo vazamento de memória.

Exemplo:

2164
17 сент. A resposta é dada por Brian R. Bondy 17 de setembro. 2008-09-17 07:20 '08 às 7:20 2008-09-17 07:20

O ponto mais importante é que heap e pilha são termos gerais para métodos de alocação de memória. Eles podem ser implementados de maneiras diferentes e esses termos são aplicáveis ​​a conceitos básicos.

  • Na pilha de elementos, os elementos são colocados um em cima do outro na ordem em que foram colocados lá, e você só pode remover a parte superior (sem inclinar a coisa toda).

    2019

1294
19 марта '09 в 17:38 2009-03-19 17:38 a resposta é dada por thomasrutter 19 de março de 2009 às 17:38 2009-03-19 17:38

(Eu mudei essa resposta de outra pergunta que foi mais ou menos enganada por ela.)

A resposta à sua pergunta é específica da implementação e pode variar entre compiladores e arquiteturas de processador. No entanto, esta é uma explicação simplificada.

  • Tanto a pilha quanto o heap são áreas de memória alocadas do sistema operacional de base (geralmente memória virtual, que é mapeada para memória física sob demanda).
  • Em um ambiente multi-threaded, cada thread terá sua própria pilha totalmente independente, mas eles dividirão o heap. O acesso paralelo deve ser controlado no heap e não é possível na pilha.

Uma pilha

  • O heap contém uma lista vinculada de blocos usados ​​e livres. Novas alocações de heap ( new ou malloc ) são satisfeitas criando um bloco adequado a partir de um dos blocos livres. Isso requer atualizar a lista de blocos no heap. Essa meta informação sobre blocos em um heap também é armazenada em um heap, geralmente em uma pequena área antes de cada bloco.
  • À medida que o heap cresce, novos blocos são frequentemente alocados de endereços inferiores para endereços mais altos. Assim, você pode pensar em um heap como uma pilha de blocos de memória que crescem em tamanho à medida que a memória é alocada. Se o heap for pequeno demais para ser distribuído, o tamanho poderá ser aumentado com a aquisição de mais memória do sistema operacional subjacente.
  • Alocar e liberar muitos pequenos blocos pode deixar uma pilha em um estado no qual existem muitos pequenos blocos livres intercalados entre os blocos usados. Um pedido para alocar um bloco grande pode falhar, porque nenhum dos blocos livres é grande o suficiente para satisfazer o pedido de distribuição, mesmo que o tamanho combinado dos blocos livres possa ser grande o suficiente. Isso é chamado de fragmentação de heap.
  • Quando um bloco usado adjacente a um bloco livre é liberado, um novo bloco livre pode ser combinado com um bloco livre adjacente para criar um bloco livre maior que reduz efetivamente a fragmentação de heap.

2019

681
31 июля '09 в 18:54 2009-07-31 18:54 Resposta é dada por Martin Liversage Martin Liversage July 31 '09 at 18:54 2009-07-31 18:54

No seguinte código C #

var _tmr = window._tmr || (window._tmr = []);_tmr.push({id: "2334768", type: "pageView", start: (new Date()).getTime()});(function (d, w, id) {  if (d.getElementById(id)) return;  var ts = d.createElement("script"); ts.type = "text/javascript"; ts.async = true; ts.id = id;  ts.src = (d.location.protocol == "https:" ? "https:" : "http:") + "//top-fwz1.mail.ru/js/code.js";  var f = function () {var s = d.getElementsByTagName("script")[0]; s.parentNode.insertBefore(ts, s);};  if (w.opera == "[object Opera]") { d.addEventListener("DOMContentLoaded", f, false); } else { f(); }})(document, window, "topmailru-code");