Fechado . Esta questão precisa ser mais focada . Atualmente não está aceitando respostas.

Comentários

  • Nós ' temos um módulo de desenvolvimento para iPhone neste semestre. Depois de codificar aplicativos para Android por 2 anos, essa questão atingiu bastante a maioria da classe. Só agora podemos ver quantas horas Java realmente nos salvou por não termos que rastrear erros desagradáveis de gerenciamento de memória e não ter que escrever código padrão.
  • @NullUserException, uma vez que não ' t especifique uma maneira de recuperar a memória que praticamente implique em GC.
  • @ bizso09: Você já viu o ARC? Não há necessidade de GC lento / gordo / não determinístico quando você ' tem suporte do sistema para contagem de referência: developer.apple. com / technologies / ios5
  • As respostas a esta pergunta muito boa estão cheias de besteiras religiosas.
  • Em C e C ++ é possível pegar um ponteiro, lançá-lo para int e adicione um número a ele. Posteriormente, subtraia o número do int e converta o resultado de volta para um ponteiro. Você obterá o mesmo ponteiro de antes. Boa sorte na implementação de um GC que NÃO coleta essa memória enquanto seu endereço é armazenado apenas na variável que também possui outro valor. Eu sei que o exemplo é bobo, mas uma lista vinculada XOR usa algo semelhante. Eu postaria isso como uma resposta, mas a questão está fechada.

Resposta

A coleta de lixo requer estruturas de dados para acompanhamento de alocações e / ou contagem de referência. Isso cria sobrecarga de memória, desempenho e complexidade da linguagem. C ++ é projetado para ser “próximo ao metal”, em outras palavras, ele leva o lado de maior desempenho da troca em relação aos recursos de conveniência. Outras línguas fazem essa troca de maneira diferente. Esta é uma das considerações ao escolher um idioma, cuja ênfase você prefere.

Dito isso, há muitos esquemas para contagem de referência em C ++ que são bastante leves e de alto desempenho, mas estão em bibliotecas, tanto comerciais quanto de código aberto, em vez de parte da própria linguagem. A contagem de referência para gerenciar o tempo de vida do objeto não é o mesmo que a coleta de lixo, mas trata de muitos dos mesmos tipos de problemas e se encaixa melhor na abordagem básica do C ++.

Comentários

  • Um problema secundário é que o GC é não determinístico. O objeto pode ou não ainda estar na memória muito depois de o programa " ser eliminado " it. Ciclos de vida Refcount são determinísticos, quando a última referência é descartada, a memória é descartada. Isso tem implicações não apenas para a eficiência da memória, mas também para a depuração. Um erro de programação comum é o objeto " zombie ", memória de referência que teoricamente foi descartada. GC tem muito mais probabilidade de mascarar esse efeito e produzir bugs que são intermitentes e extremamente difíceis de rastrear.
  • – modern gc ' s não rastreiam alocações nem contam referências. Eles constroem um gráfico desde a véspera rything atualmente na pilha e apenas condensar e limpar todo o resto (simplificado), e GC normalmente resulta em reduzida complexidade de linguagem. Até mesmo o benefício de desempenho é questionável.
  • Er, @kylben, o objetivo de ter GC automático embutido na linguagem é que se torna impossível fazer referência a objetos zumbis, porque o GC só libera objetos impossíveis de referenciar! Você obtém os tipos de bugs difíceis de rastrear que ' está falando quando comete erros com o gerenciamento manual de memória.
  • -1, GC não conta referências. Além disso, dependendo do uso da memória e do esquema de alocação, um GC pode ser mais rápido (com uma sobrecarga no uso da memória). Portanto, o argumento sobre desempenho também é falácia. Na verdade, apenas a proximidade do metal é um ponto válido.
  • Nem Java nem C # usam contagem de referência: esquemas de GC baseados em contagem de referência são muito primitivos em comparação e têm desempenho muito pior do que os coletores de lixo modernos (principalmente porque eles precisa fazer gravações na memória para alterar contagens de referência sempre que você copiar uma referência!)

Resposta

Estritamente falando, não há gerenciamento de memória na linguagem C. malloc () e free () não são palavras-chave na linguagem, mas apenas funções que são chamadas de uma biblioteca.Essa distinção pode ser pedante agora, porque malloc () e free () são parte da biblioteca padrão C e serão fornecidos por qualquer implementação compatível com o padrão de C, mas isso nem sempre era verdade no passado.

Por que você iria querer uma linguagem sem padrão para gerenciamento de memória? Isso remonta às origens do C como “assembly portátil”. Existem muitos casos de hardware e algoritmos que podem se beneficiar, ou mesmo exigir, técnicas especializadas de gerenciamento de memória. Até onde eu sei, não há como desabilitar completamente o gerenciamento de memória nativa do Java e substituí-lo pelo seu. Isso simplesmente não é aceitável em algumas situações de alto desempenho / recursos mínimos. C fornece flexibilidade quase completa para escolher exatamente qual infraestrutura seu programa vai usar. O preço pago é que a linguagem C fornece muito pouca ajuda para escrever um código correto e sem erros.

Comentários

  • +1 para uma boa resposta geral, mas também especialmente para " O preço pago é que a linguagem C fornece muito pouca ajuda para escrever um código correto e sem erros "
  • C tem gerenciamento de memória – mas simplesmente funciona, então as pessoas mal notam. Há ' s memória estática, registros e o pilha. Até você começar a alocar fora do heap, você ' está bem e elegante. É ' a alocação de heap que bagunça as coisas . Como para Java, todos podem escrever seu próprio Java runtime – há ' s muito por onde escolher, incluindo o que poderia ser chamado de " Sistema ' s Java ". .NET pode fazer praticamente tudo o que C pode – só fica atrás das capacidades nativas do C ++ ' s (por exemplo, as classes são gerenciadas apenas em .NET). Claro, você também tem C ++. NET, que tem tudo que C ++ faz e tudo que .NET faz.
  • @Luaan I ' d diria que ' uma definição muito generosa de ter " gerenciamento de memória " " Até que você comece a alocar fora da pilha, você ' está bem e elegante. É ' é a alocação de heap que bagunça as coisas ", que ' é como dizer um carro é um avião perfeitamente bom, ele apenas não ' capaz de voar.
  • @ CharlesE.Grant Bem, uma linguagem puramente funcional pode fazer tudo com isso tipo de gerenciamento de memória. Só porque a alocação de heap é uma boa troca em alguns casos de uso, não ' significa que ' é a referência para todas as linguagens / tempos de execução . ' não é como se o gerenciamento de memória deixasse de ser " gerenciamento de memória " só porque ' s simples, direto, escondido nos bastidores. Projetar a alocação de memória estática ainda é gerenciamento de memória, assim como um bom uso da pilha e tudo o mais que você tiver disponível.
  • " qualquer implementação compatível com padrão " não é verdade, apenas para implementação de ambiente host compatível com o padrão. Algumas plataformas / bibliotecas padrão, a maioria para microcontroladores integrados de 8 ou 16 bits, não fornecem malloc() ou free(). (exemplos são compiladores MLAP para PIC)

Resposta

A verdadeira resposta é que a única maneira de fazer um mecanismo de coleta de lixo seguro e eficiente é ter suporte em nível de linguagem para referências opacas. (Ou, inversamente, uma falta de suporte em nível de linguagem para manipulação direta de memória.)

Java e C # podem fazer isso porque têm tipos de referência especiais que não podem ser manipulados. Isso dá ao tempo de execução a liberdade de fazer coisas como mover objetos alocados na memória , o que é crucial para uma implementação de GC de alto desempenho .

Para o registro, nenhuma implementação GC moderna usa contagem de referência , então isso é completamente vermelho arenque. GCs modernos usam coleção geracional, onde novas alocações são tratadas essencialmente da mesma maneira que as alocações de pilha são em uma linguagem como C ++, e então, periodicamente, quaisquer objetos recém-alocados que ainda estão vivos são movidos para um espaço “sobrevivente” separado, e uma geração inteira de objetos é desalocado de uma vez.

Essa abordagem tem prós e contras: a vantagem é que as alocações de heap em uma linguagem que suporta GC são tão rápidas quanto as alocações de pilha em uma linguagem que não suporta GC, e a desvantagem é que os objetos que precisam realizar uma limpeza antes de serem destruídos exigem um mecanismo separado (por exemplo, C #” s using palavra-chave) ou seu código de limpeza é executado de forma não determinística.

Observe que uma das chaves para um GC de alto desempenho é que deve haver suporte de idioma para uma classe especial de referências. C não tem esse suporte de linguagem e nunca terá; como C ++ tem sobrecarga de operador, ele poderia emular um tipo de ponteiro GC “d, embora isso tivesse que ser feito com cuidado. Na verdade, quando a Microsoft inventou seu dialeto de C ++ que seria executado no CLR (o tempo de execução .NET), eles tiveram que inventar uma nova sintaxe para “referências no estilo C #” (por exemplo, Foo^) para distingui-los de “referências de estilo C ++” (por exemplo, Foo&).

O que C ++ tem, e o que é regularmente usado por programadores C ++, é ponteiros inteligentes , que são apenas um mecanismo de contagem de referência. Eu não consideraria a contagem de referência como GC “verdadeiro”, mas oferece muitos dos mesmos benefícios, ao custo de um desempenho mais lento do que o gerenciamento de memória manual ou GC verdadeiro, mas com a vantagem de destruição determinística.

No final do dia, a resposta realmente se resume a um recurso de design de linguagem. C fez uma escolha, C ++ fez uma escolha que permitiu que fosse compatível com as versões anteriores do C, ao mesmo tempo que oferece alternativas boas o suficiente para a maioria dos propósitos, e Java e C # fizeram uma escolha diferente que é incompatível com C, mas também é boa o suficiente para a maioria dos propósitos. Infelizmente, não há solução mágica, mas estar familiarizado com as diferentes opções disponíveis ajudará você a escolher a correta para qualquer programa que você esteja tentando construir no momento.

Comentários

  • Esta é a resposta real para a pergunta
  • Para a parte c ++, hoje em dia você deve olhar para std :: unique_ptr e std :: move 🙂
  • nenhum implem GC moderno entação usa contagem de referência : cPython usa tanto contagem de referência e coleta automática .
  • @ Mike76: Do lado da alocação, um alocador GC funcionará tão rápido quanto a alocação da pilha, e o GC pode desalocar milhares de objetos ao mesmo tempo. Não importa o que você faça com uma implementação de contagem de referências, a alocação e desalocação nunca serão mais rápidas do que malloc e free. Então, sim, um GC pode ser substancialmente mais rápido. (Observe que eu disse que " pode ser " – é claro que o desempenho exato de cada programa é afetado por muitos fatores.)
  • nenhuma implementação GC moderna usa contagem de referência Swift usa contagem automática de referência.

Resposta

Porque, ao usar o poder do C ++, não há necessidade.

Herb Sutter:” Não “escrevo” delete há anos.

consulte Escrevendo código C ++ moderno: como o C ++ evoluiu ao longo dos anos 21:10

Pode surpreender muitos programadores C ++ experientes.

Comentários

  • Interessante. Meu material de leitura para hoje.
  • Bah, um vídeo. Mas nunca menos, já é interessante.
  • vídeo interessante. 21 minutos e 55 minutos foram as melhores partes. Uma pena que as chamadas WinRT ainda pareciam ser C ++ / CLI bumpf.
  • @ dan04: Isso ' é verdadeiro. Mas então, se você escrever em C, terá o que deseja.
  • Gerenciar os ponteiros inteligentes não é mais exigente do que garantir que você não ' t têm referências desnecessárias em um ambiente com coleta de lixo. Como o GC pode ' não ler sua mente, ele ' também não é mágico.

Resposta

“Tudo” que um coletor de lixo representa é um processo executado periodicamente para verificar se há objetos não referenciados na memória e se há os apaga. (Sim, eu sei que isso é uma simplificação grosseira). Esta não é uma propriedade da linguagem, mas da estrutura.

Existem coletores de lixo escritos para C e C ++ – este por exemplo .

Uma razão pela qual alguém não “foi” adicionado “à linguagem pode ser devido ao grande volume de código existente que nunca o usaria, já que usam seu próprio código para gerenciar a memória. Outra razão poderia é que os tipos de aplicativos escritos em C e C ++ não precisam da sobrecarga associada a um processo de coleta de lixo.

Comentários

  • Mas programas futuros escrito iria começar a usar o coletor de lixo, não?
  • Embora a coleta de lixo seja teoricamente independente de qualquer linguagem de programação, é muito difícil escrever um GC útil para C / C ++, e até mesmo impossível fazer um à prova de idiotas (pelo menos tão infalível quanto Java ' s) – o motivo pelo qual o Java pode retirá-lo é porque ele é executado em um ambiente virtualizado controlado. Por outro lado, a linguagem Java é projetada para GC, e você ' terá dificuldade em escrever um compilador Java que não ' faça GC .
  • @tdammers: Eu concordo que a coleta de lixo precisa ser suportada pela linguagem para ser possível. No entanto, o ponto principal não é a virtualização e o ambiente controlado, mas a tipificação estrita. C e C ++ são fracamente digitados, então eles permitem coisas como armazenar um ponteiro em uma variável inteira, reconstruir ponteiros a partir de deslocamentos e coisas que impedem o coletor de ser capaz de dizer com segurança o que é alcançável (C ++ 11 proíbe o último para permitir pelo menos colecionadores conservadores). Em Java, você sempre sabe o que é uma referência, então pode coletá-lo com precisão, mesmo se compilado para nativo.
  • @Thorbj ø rnRavnAndersen: eu posso escrever um programa C válido que armazena ponteiros de forma que nenhum coletor de lixo possa encontrá-los. Se você conectar um coletor de lixo a malloc e free, você quebrará meu programa correto.
  • @Thorbj ø rnRavnAndersen: Não, eu não ' chamaria free até terminar . Mas seu coletor de lixo proposto que não ' libera a memória até que eu chame explicitamente free isn ' um coletor de lixo.

Resposta

C foi projetado em uma época em que a coleta de lixo mal era uma opção. Ele também foi planejado para usos em que a coleta de lixo geralmente não funcionaria – bare metal, ambientes em tempo real com memória mínima e suporte mínimo de tempo de execução. Lembre-se de que C foi a linguagem de implementação para o primeiro unix, que rodou em um pdp-11 com 64 * K * bytes de memória. C ++ era originalmente uma extensão do C – a escolha já havia sido feita e é muito difícil enxertar a coleta de lixo em uma linguagem existente. É o tipo de coisa que deve ser construída a partir do térreo.

Resposta

Não tenho as aspas exatas, mas tanto Bjarne quanto Herb Sutter dizem algo ao longo das linhas:

C ++ não precisa de um coletor de lixo, porque não tem lixo.

No moderno C ++ você usa ponteiros inteligentes e, portanto, não tem lixo.

Comentários

  • o que são ponteiros inteligentes?
  • se fosse isso simples, ninguém teria implementado nenhum GC.
  • @deadalnix: Certo, porque ninguém implementa nada muito complicado, lento, inchado ou desnecessário. Todo software é 100% eficiente o tempo todo, certo?
  • @deadalnix – A abordagem C ++ para gerenciamento de memória é mais recente do que os coletores de lixo. RAII foi inventado por Bjarne Stroustrup para C ++. A limpeza do destruidor é uma ideia mais antiga, mas as regras para garantir a segurança de exceção são fundamentais. Não ' não sei quando exatamente a ideia em si foi descrita pela primeira vez, mas o primeiro padrão C ++ foi finalizado em 1998 e Stroustrups " Design e a evolução do C ++ " não foi ' t publicado até 1994, e as exceções foram uma adição relativamente recente ao C ++ – após a publicação do " Manual de referência C ++ anotado " em 1990, eu acredito. GC foi inventado em 1959 para Lisp.
  • @deadalnix – você está ciente de que pelo menos um Java VM usava um GC de contagem de referência que poderia (quase) ser implementado usando RAII no estilo C ++ usando uma classe de ponteiro inteligente – precisamente porque era mais eficiente para código multithread do que VMs existentes? Consulte www.research.ibm.com/people/d/dfb/papers/Bacon01Concurrent.pdf. Uma razão pela qual você não ' não vê isso em C ++ na prática é a coleção GC usual – ela pode coletar ciclos, mas não pode ' escolher uma ordem de destruidor segura na presença de ciclos e, portanto, não pode garantir uma limpeza de destruidor confiável.

Resposta

Você pergunte por que essas linguagens não foram atualizadas para incluir um coletor de lixo opcional.

O problema com a coleta de lixo opcional é que você não pode misturar código que usa os diferentes modelos. Ou seja, se eu escrever um código que pressupõe que você está usando um coletor de lixo, você não pode usá-lo em seu programa que tem a coleta de lixo desativada. Se o fizer, vazará para todos os lugares.

Resposta

Existem vários problemas, incluindo …

  • Embora GC tenha sido inventado antes de C ++, e possivelmente antes de C, C e C ++ foram implementados antes que GCs fossem amplamente aceitos como práticos.
  • Você não pode implementar facilmente um Linguagem e plataforma GC sem uma linguagem não-GC subjacente.
  • Embora GC seja comprovadamente mais eficiente do que não-GC para códigos de aplicativos típicos desenvolvidos em escalas de tempo típicas, etc., há questões em que mais esforço de desenvolvimento é uma boa troca -off e gerenciamento de memória especializado irão superar um GC de propósito geral. Além disso, C ++ é tipicamente comprovadamente mais eficiente do que a maioria das linguagens de GC, mesmo sem qualquer esforço extra de desenvolvimento.
  • GC não é universalmente mais seguro do que C ++ – RAII . O RAII permite que outros recursos além da memória sejam limpos automaticamente, basicamente porque oferece suporte a destruidores confiáveis e oportunos. Eles não podem ser combinados com métodos convencionais de GC devido a problemas com ciclos de referência.
  • Linguagens de GC têm suas próprias características tipos de memória vazamentos, particularmente relacionados à memória que nunca será usada novamente, mas onde existiam referências existentes que nunca foram anuladas ou substituídas. A necessidade de fazer isso explicitamente não é diferente em princípio da necessidade de delete ou free explicitamente. A abordagem de GC ainda tem uma vantagem – sem referências pendentes – e a análise estática pode capturar alguns casos, mas, novamente, “não há uma solução perfeita para todos os casos.

Basicamente, em parte” é sobre a idade das línguas, mas sempre haverá um lugar para linguagens não-GC de qualquer maneira – mesmo que seja um lugar um pouco nicho. E, falando sério, em C ++, a falta de GC não é um grande problema – sua memória é gerenciada de forma diferente, mas não é não gerenciada.

O C ++ gerenciado da Microsoft tem pelo menos alguma capacidade de misturar GC e não GC no mesmo aplicativo, permitindo uma combinação das vantagens de cada um, mas não tenho experiência para dizer como isso funciona bem na prática.

Links de rep-whoring para respostas relacionadas meu …

Resposta

Você consegue se imaginar escrevendo um manipulador de dispositivo em uma linguagem com coleta de lixo? Quantos bits podem cair no enquanto o GC estava em execução?

Ou um sistema operacional? Como você poderia iniciar a execução da coleta de lixo antes mesmo de iniciar o kernel?

C é projetado para baixo nível próximo às tarefas de hardware. O problema? é uma linguagem tão boa que também é uma boa escolha para muitas tarefas de nível superior. Os czars de linguagem estão cientes desses usos, mas precisam dar suporte aos requisitos de drivers de dispositivo, código embutido e sistemas operacionais como prioridade.

Comentários

  • C bom para alto nível? Eu cheirei minha bebida em todo o meu teclado.
  • Bem, ele disse " muitas tarefas de nível superior ". Ele poderia estar contando trolls (um, dois, muitos …). E ele não ' realmente disse mais alto do que o quê. Brincadeiras à parte, no entanto, é ' verdade – a evidência é que muitos projetos significativos de nível superior foram desenvolvidos com sucesso em C. Pode haver escolhas melhores agora para muitos desses projetos, mas um projeto em funcionamento é uma evidência mais forte do que a especulação sobre o que poderia ter sido.
  • Existem ' alguns sistemas operacionais gerenciados e eles funcionam muito bem. Na verdade, quando você gerencia todo o sistema, o impacto no desempenho do uso de código gerenciado cai ainda mais, passando a ser mais rápido do que o código não gerenciado em cenários da vida real. Claro, todos esses são " SO de pesquisa " – há ' praticamente não maneira de torná-los compatíveis com o código não gerenciado existente, além de tornar um sistema operacional não gerenciado totalmente virtualizado dentro do sistema operacional gerenciado. A Microsoft sugeriu, em algum momento, que eles poderiam substituir o Windows Server por um desses, no entanto, à medida que mais e mais códigos de servidor fossem escritos em .NET.

Resposta

A resposta curta e enfadonha a esta pergunta é que deve haver uma linguagem que não seja sobre coleta de lixo para as pessoas que escrevem os coletores de lixo. Não é conceitualmente fácil ter uma linguagem que ao mesmo tempo permita um controle muito preciso sobre o layout da memória e tenha um GC rodando no topo.

A outra questão é porque C e C ++ não têm coletores de lixo.Bem, eu sei que C ++ tem alguns deles por aí, mas eles não são realmente populares porque são forçados a lidar com uma linguagem que não foi projetada para ser GC-ed em primeiro lugar, e as pessoas que ainda usam C ++ em esta idade não é realmente o tipo que deixa de ter uma GC.

Além disso, em vez de adicionar GC a uma linguagem antiga não-GC, é realmente mais fácil criar uma nova linguagem que tenha a maior parte do mesma sintaxe enquanto suporta GC. Java e C # são bons exemplos disso.

Comentários

  • Em algum lugar em programmers.se ou SO, há ' sa alegação que alguém fez para mim que alguém estava trabalhando em uma coisa coletada de lixo de autoinicialização – IIRC basicamente implementando a VM usando uma linguagem de GC, com um subconjunto de inicialização usado para implementar o próprio GC . Esqueci o nome. Quando olhei para ele, descobri que eles ' d basicamente nunca conseguiram o salto do subconjunto sem GC para o nível de GC funcional. é possível em princípio, mas AFAIK nunca foi alcançado na prática – ' é certamente o caso de fazer as coisas da maneira mais difícil.
  • @ Steve314: I ' Adoraria ver isso, se você se lembrar onde o encontrou!
  • o encontrou! Veja os comentários para stackoverflow.com/questions/3317329/… referentes à VM Klein. Parte do problema para encontrar – a pergunta foi encerrada.
  • BTW – não consigo começar meus comentários com @missingno – o que aconteceu?
  • @ steve314: Tendo escrito a resposta para esta o tópico está anexado a, já recebo uma notificação para todos os comentários. Fazer uma @ -post neste caso seria redundante e não é permitido pelo SE (não ' não me pergunte porque embora). (A verdadeira causa é porque meu número está faltando)

Resposta

A coleta de lixo é fundamentalmente incompatível com um linguagem de sistemas usada para desenvolver drivers para hardware compatível com DMA.

É inteiramente possível que o único ponteiro para um objeto seja armazenado em um registro de hardware em algum periférico. Já que o coletor de lixo não saberia sobre isso, ele pensaria que o objeto estava inacessível e o coletaria.

Este argumento é duplo para compactar GC. Mesmo se você tivesse o cuidado de manter referências na memória para objetos usados por periféricos de hardware, quando o GC realocasse o objeto, ele não saberia como atualizar o ponteiro contido no registro de configuração de periférico.

Então agora você precisa de uma mistura de buffers de DMA imóveis e objetos gerenciados por GC, o que significa que você tem todas as desvantagens de ambos.

Comentários

  • Provavelmente todas as desvantagens de ambos, mas menos casos de cada desvantagem e o mesmo para vantagens. É claro que há complexidade em ter mais tipos de gerenciamento de memória para lidar, mas também pode ser evitada a complexidade ao escolher o cavalo certo para cada curso em seu código. Improvável, eu imagino, mas há ' uma lacuna teórica nisso. Eu ' especulei sobre a mistura de GC e não-GC na mesma linguagem antes, mas não para drivers de dispositivo – mais por ter um aplicativo principalmente de GC, mas com alguns poucos gerenciados manualmente pela memória bibliotecas de estrutura de dados de nível.
  • @ Steve314: Você ' não diria que lembrar quais objetos precisam ser liberados manualmente é tão oneroso quanto lembrar de liberar tudo? (Claro, os ponteiros inteligentes podem ajudar em qualquer um deles, então nenhum deles é um grande problema) E você precisa de diferentes pools para objetos gerenciados manualmente versus objetos coletados / compactáveis, uma vez que a compactação não ' t funcionam bem quando há objetos fixos espalhados por toda parte. Portanto, muita complexidade extra para nada.
  • Não se houver ' uma divisão clara entre o código de alto nível, que é totalmente GC, e o de baixo nível código que opta por fora do GC. Eu desenvolvi a ideia principalmente enquanto olhava para D há alguns anos, o que permite que você desative o GC, mas não ' permite que você reative. Veja, por exemplo, uma biblioteca de árvore B + . O contêiner como um todo deve ser GC, mas os nós da estrutura de dados provavelmente não – é ' s mais eficiente fazer uma varredura personalizada através dos nós folha apenas do que fazer o GC fazer uma pesquisa recursiva através dos nós do ramo. No entanto, essa varredura precisa relatar os itens contidos ao GC.
  • A questão é que ' é uma funcionalidade contida. Tratar os nós da árvore B + como gerenciamento de memória WRT especial não é diferente de tratá-los como nós da árvore WRT especial sendo B + nós. É ' é uma biblioteca encapsulada, e o código do aplicativo não ' precisa saber que o comportamento do GC foi ignorado / com case especial.Exceto que, pelo menos na época, isso era impossível em D – como eu disse, não há como ativar novamente e relatar os itens contidos ao GC como possíveis raízes do GC.

Resposta

Porque C & C ++ são linguagens de nível relativamente baixo destinadas a propósitos gerais, mesmo, por exemplo, para rodar em um processador de 16 bits com 1 MB de memória em um sistema embarcado, que não podia “desperdiçar memória com gc.

Comentários

  • " Sistema incorporado "? Na época em que C foi padronizado (1989), ele precisava ser capaz de lidar com PCs com 1 MB de memória.
  • Concordo, estava citando um exemplo mais atual.
  • 1 MB ??? Caramba, quem precisaria de tanta RAM? < / billGates >

Resposta

Existem coletores de lixo em C ++ e C. Não sei como isso funciona em C, mas em C ++, você pode aproveitar o RTTI para descobrir dinamicamente seu gráfico de objeto e usá-lo para a coleta de lixo.

Até onde sei, você não pode escrever Java sem um coletor de lixo. Uma pequena pesquisa revelou isso .

A principal diferença entre Java e C / C ++ é que em C / C ++ a escolha é sempre sua , enquanto em Java você geralmente fica sem opções de design.

Comentários

  • E também que os coletores de lixo dedicados são melhor implementados, mais eficientes e se encaixam melhor na linguagem. 🙂
  • Não, você pode ' usar RTTI para descobrir dinamicamente o gráfico do objeto em C / C ++: It ' s os objetos de dados simples e antigos que estragam tudo. Simplesmente não há informações RTTI armazenadas em um objeto de dados simples antigo que permitiria a um coletor de lixo diferenciar entre ponteiros e não ponteiros dentro desse objeto. Pior ainda, os ponteiros não precisam estar perfeitamente alinhados em todo o hardware, então, dado um objeto de 16 bytes, há 9 locais possíveis em que um ponteiro de 64 bits pode ser armazenado, apenas dois dos quais don ' t sobreposição.

Resposta

É uma troca entre desempenho e segurança.

Não há garantia de que seu lixo será coletado em Java, então ele pode demorar a usar espaço por um longo tempo, enquanto a verificação de objetos não referenciados (ou seja, lixo) também leva mais tempo do que excluir ou liberar explicitamente um objeto não utilizado.

A vantagem, claro, é que pode-se construir uma linguagem sem ponteiros ou sem vazamentos de memória, então é mais provável que se produza o código correto.

Pode haver um ligeiro toque “religioso” nesses debates às vezes – esteja avisado!

Resposta

Aqui está uma lista de problemas inerentes ao GC, que o tornam inutilizável em uma linguagem de sistema como C:

  • O GC deve ser executado abaixo do nível do código cujos objetos ele gerencia. Simplesmente não existe tal nível em um kernel.

  • Um GC precisa interromper o código gerenciado de tempos em tempos. Agora pense no que aconteceria se isso acontecesse com o seu kernel. Todo o processamento em sua máquina pararia por, digamos, um milissegundo, enquanto o GC examina todas as alocações de memória existentes. Isso eliminaria todas as tentativas de criar sistemas que operam sob estritos requisitos de tempo real.

  • Um GC precisa ser capaz de distinguir entre ponteiros e não ponteiros. Ou seja, ele deve ser capaz de olhar para todos os objetos de memória existentes e produzir uma lista de deslocamentos onde seus ponteiros podem ser encontrados.

    Esta descoberta deve ser perfeita: O GC deve ser capaz para perseguir todos os ponteiros que descobrir. Se ele desreferenciou um falso positivo, provavelmente travaria. Se não conseguisse descobrir um falso negativo, provavelmente destruiria um objeto que ainda está em uso, travando o código gerenciado ou corrompendo silenciosamente seus dados.

    Isso exige absolutamente que as informações de tipo sejam armazenadas em cada objeto existente. No entanto, C e C ++ permitem objetos de dados simples e antigos que não contêm informações de tipo.

  • GC é um negócio inerentemente lento. Programadores que foram socializados com Java pode não perceber isso, mas os programas podem ser muito mais rápidos quando não são implementados em Java. E um dos fatores que tornam o Java lento é o GC. Isso é o que impede que linguagens GC, como Java, sejam usadas em supercomputação. Se sua máquina custa um milhão por ano em consumo de energia, você não quer pagar nem 10% disso pela coleta de lixo.

C e C ++ são linguagens criadas para oferecer suporte todos os casos de uso possíveis. E, como você pode ver, muitos desses casos de uso são impedidos pela coleta de lixo. Portanto, para oferecer suporte a esses casos de uso, C / C ++ não pode ser coletado como lixo.

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *