Pergunta

Observe que isso não é sobre .NET CLR que a Microsoft está empurrando a atmosfera para evangelizar o conceito de código gerenciado.A maioria de vocês sabem que o código gerenciado tem sido em torno de algum tempo e não é muito relacionadas com a ciência de foguetes.

O que eu gostaria de saber é por que o conceito de segurança de tempo de execução na evolução dos computadores veio tão tarde.

Eu sei que isso é como perguntar "por que não o primeiro Modelo T da Ford vem com airbags e cintos de segurança?".A relevância da questão ainda permanece, apesar disso, porém, porque é bem dentro da natureza humana para proteger perante perigos conhecidos.E. g.a primeira T-Ford não fui rápido o suficiente para motivar para a pesquisa.Não foi rápido o suficiente para que as pessoas fatal julgamento erros tantas vezes que poderia motivar o cinto de segurança, conforme legislação e norma em muitos países.

No computador a evolução é quase o contrário.Começamos com assembler, o equivalente a condução de um T-Ford no 200mph com um tapa-olho.Eu tive o prazer de conversating com alguns antigos caminhoneiros a partir desta época, a ouvir essas histórias sobre a mão-de montagem assembly de código, humanos, depuradores, grillion linhas de código, etc.Se realmente desagradável erro em C, podemos acabar com um ecrã azul.Décadas atrás, você poderia acabar com hardware danificado, e deus sabe que mais.Mas é um mistério para mim - tantas décadas, e tudo o que fizemos para fazer cair a menos doloroso foi o bluescreen (desculpe a utilizar o MS como arquétipo para nada).

Não é só dentro de natureza humana para proteger contra perigos conhecidos, é também dentro de qualquer programador da natureza para automatizar e sistematizar instalações comuns, como verificação de erros, de diagnóstico de memória, frameworks de logging, backup, manutenção, etc., etc.

Por que não programadores e os seres humanos começam a automatizar a tarefa de assegurar que o código de alimentação para o sistema não irá prejudicar o sistema?.Sim, claro, desempenho.Mas hey, isso foi bem antes de qualquer seriamente penetrante padrão de hardware.Por que não motherboards obter projetado com arquiteturas de barramento e extra processadores para facilitar o "código gerenciado"?

Existe alguma metáfora para o Modelo T da Ford não ser rápida o suficiente para que eu estou ausente?

Foi útil?

Solução

Vamos pensar isso dos primeiros princípios.

Uma plataforma gerenciada fornece uma área de caixa de areia relativamente para executar o código do programa criado do idioma de alto nível para um formulário mais adequado para ser executado pela plataforma (IL Bytecodes). Também existem recursos de utilidade, como coleta de lixo e carregamento de módulos.

Agora pense em um aplicativo nativo - o sistema operacional fornece uma área relativamente sandbox (um processo) para executar o código do programa criado de um idioma de alto nível para um formulário mais adequado para ser executado pela plataforma (X86 OpCodes). Existem também recursos de utilitário, como gerenciamento de memória virtual e carregamento de módulos.

Não há muita diferença, acho que a razão pela qual gerenciamos a plataforma em primeiro lugar é simplesmente porque facilita a codificação da plataforma. Ele deve tornar o código portátil entre os sistemas operacionais, mas a MS não se importava com isso. A segurança faz parte da plataforma gerenciada, mas deve fazer parte do sistema operacional. Seu aplicativo gerenciado pode escrever arquivos e similar, assim como um processo normal. Restringir que é um recurso de segurança, não é um aspecto de uma plataforma gerenciada que não existe no nativo.

Por fim, eles poderiam ter colocado todos esses recursos gerenciados em um conjunto de DLLs nativos e descartado a idéia do bytecode intermediário, compilando o código nativo. Recursos "gerenciados" como o GC são facilmente possíveis em heaps nativos - consulte o Boehm C ++ um para um exemplo.

Eu acho que a MS fez em parte porque tornou o compilador mais fácil de escrever, e em parte porque foi assim que Java foi feito (e .NET é muito descendente de Java, mesmo que apenas em espírito), embora Java tenha feito dessa maneira para fazer cruz -Plataform Codificação possível, algo que a MS não se importa.

Então, por que não conseguimos código gerenciado desde o início - porque todas as coisas que você mencionou como parte do código 'gerenciado' são o código nativo. As plataformas gerenciadas que temos hoje são simplesmente uma abstração adicional na parte superior de uma plataforma já abstraída. Os idiomas de alto nível tiveram mais recursos adicionados a eles para protegê-lo de si mesmo, os transbordamentos de buffer são uma coisa do passado, mas não há razão para que eles não tenham sido implementados em C quando C foi inventado pela primeira vez. É só que eles não estavam. Talvez a retrospectiva faça parecer que esses recursos estavam faltando, mas tenho certeza que daqui a 10 anos, perguntaremos "Por que C# não implementou o recurso obviamente útil XYZ como temos hoje"

Outras dicas

Código gerenciado de segurança incorporado, etc.tem sido ao redor por um longo tempo.

Simplesmente não havia espaço para ela no PC original da plataforma e nunca cheguei adicionado mais tarde.

O venerável mainframe IBM tem protegido endereçamento, intocável kernal bibliotecas, baseado na função de segurança, etc.etc.desde os anos 70.Além de todos os que o código Assembler era gerido por um sofisticado (para o tempo) sistema de gerenciamento de alterações.(Univac, Burroughs, etc, tinham algo semelhante.)

Unix tinha bastante decente de segurança interna, desde o início (e não mudou muito ao longo dos anos).

Então eu acho que isso é muito windows/web problema de espaço.

Nunca houve um mainframe vírus!A maioria das transações financeiras no mundo passam através desses sistemas, em algum momento, então não é como se fosse um alvo atraente.

O interno IBM sistema de correio fez sediar a primeira 'trojan' embora!

Na verdade, o código gerenciado já existe há muito tempo. Considerar:

  • Lisp
  • Conversa fiada
  • Básico (sabor original)

Todos forneceram ambientes operacionais semelhantes ao sistema que protegeram o uso dos problemas de memória e outros problemas de controle de recursos. E todos foram falhas relativas (o básico só realmente conseguiu quando foram introduzidos recursos como Peek & Poke, que lhe permitiram mexer com o sistema subjacente).

Os computadores não eram poderosos o suficiente e torná -los poderosos o suficiente era muito caro. Quando você só tem recursos limitados à sua disposição, todos os bytes e o ciclo da CPU contam.

O primeiro computador que usei foi um Espectro Sinclair ZX em 1982. Tinha menos RAM (16K) do que o tamanho de um único arquivo de font do Windows hoje. E isso foi relativamente recentemente, na era do computador em casa. Antes de meados da década de 1970, a idéia de ter um computador em sua casa era inconcebível.

Apenas para o registro, nunca compilamos a montagem compilada à mão. Código de linguagem de montagem montados à mão. Agora isso está claro ...

Sua analogia está nublando a pergunta porque a velocidade do carro não é análoga à velocidade do computador nesse sentido: a velocidade crescente do carro exigiu as mudanças na segurança do automóvel, mas não é a velocidade aumentada do computador que impulsiona o Necessidade de mudanças na segurança do computador, é o aumento da conectividade. De um ângulo ligeiramente diferente: para o carro, a velocidade crescente é o dirigindo tecnologia para aumentar a segurança. Para os computadores, o aumento da velocidade é o possibilitando tecnologia para aumentar a segurança.

Então, os primeiros carros foram seguros em acidentes porque eram lentos. Os primeiros computadores estavam seguros porque não estavam em rede.

Agora, os carros são tornados mais seguros através de cintos de segurança, airbags, ABS, dispositivos anti-colisão e assim por diante. Os computadores são protegidos por meio de técnicas adicionais, embora você ainda não consiga superar o cabo de rede.

Isso é uma simplificação, mas acho que fica no coração. Não precisávamos dessas coisas naquela época, porque os computadores não estavam conectados à rede.

A mesma razão pela qual não havia trens há 300 anos. A mesma razão pela qual não havia telefones celulares há 30 anos. A mesma razão pela qual ainda não temos uma máquina de teletransporte.

A tecnologia evolui com o tempo, é chamada de evolução.

Os computadores não eram poderosos o suficiente naquela época. A execução de um coletor de lixo em segundo plano te mataria o desempenho do aplicativo.

Falando à sua pergunta sobre por que os computadores não tinham os mecanismos de proteção no nível do código gerenciado, e não por que as VMs não conseguiram executar em hardware lento (já explicado em outras postagens). A resposta curta é que foi. As CPUs foram projetadas para lançar uma exceção quando o código ruim acontecesse para que não danificasse o sistema. O Windows lida com isso notoriamente mal, mas há outros OSS por aí. O Unix passa como sinais para que os programas sejam encerrados sem derrubar o sistema. Realmente, se você está executando ou não o código gerenciado ou não, uma exceção de ponteiro nulo resultará da mesma maneira - na terminação do programa. A memória virtual garante que os programas não mexam com outro código, então tudo o que eles podem fazer é se machucar.

O que me leva ao meu segundo ponto. Tudo isso é desnecessário se você souber o que está fazendo. Se eu quero manter meus móveis limpos, simplesmente não solto comida. Não preciso cobrir minha casa em plástico, só tenho que ter cuidado. Se você é um codificador desleixado, a melhor VM do mundo não vai salvar você, ele apenas permitirá que você execute seu código desleixado sem nenhum ruído. Além disso, o código de porção é fácil se você usar o encapsulamento adequado. Quando você é um bom codificador, o código gerenciado não ajuda extensivamente. É por isso que nem todos estão usando. É simplesmente uma questão de preferência, não melhor / pior.

No que diz respeito à segurança do tempo de execução, não há nada que um compilador de código P possa prever que um código de máquina não pode, e nada que um intérprete de código gerenciado possa lidar com o fato de o sistema operacional não pode (ou não). As placas -mãe com ônibus extras, CPUs e conjuntos de instruções custam muito mais dinheiro - trata -se da taxa de custo/desempenho.

Em 1970, o custo da memória era Cerca de US $ 1/bit (sem inflação). Você não pode pagar a coleta de lixo de luxo com custos como esse.

Eu acho que a maioria das perguntas, "Por que não tivemos X na programação de anos atrás" A resposta é a alocação de velocidade/recursos. Com recursos limitados, eles precisavam ser gerenciados da maneira mais eficaz possível. O tipo de gerenciamento de propósito geral associado ao código gerenciado seria muito consumido por recursos para ter sido benéfico em aplicativos críticos de desempenho da época. Isso também faz parte do motivo pelo qual o código crítico de desempenho de hoje ainda está escrito em C, Fortran ou Assembler.

Por que não apenas construímos aviões e naves espaciais de uma só vez, em vez de mexer com cavalo e carruagem e todas as coisas tediosas?

O uso de uma linguagem intermediária requer uma de duas coisas:

  1. Interpretação em tempo de execução, que terá uma penalidade de desempenho substancial (amplamente variável-ocasionalmente 2x ou menos, mas às vezes 100x ou mais)
  2. Um compilador just-in-time, que exigirá RAM extra, e que adicionará atraso proporcional ao tamanho do programa, em vez de número de declarações executadas

Uma coisa que mudou ao longo dos anos é que muitos programas executam as partes mais usadas de seu modo muito mais vezes do que costumavam. Suponha que a primeira vez que qualquer declaração específica for executada incorer em uma penalidade 1.000 vezes mais que as execuções subsequentes. Qual será o efeito dessa penalidade em um programa em que cada declaração é executada em média 100 vezes? Qual será o efeito dessa penalidade em um programa em que cada declaração é executada em média 1.000.000 vezes?

A compilação just-in-time é possível há muito tempo, mas nos anos 80 ou 1990, o custo de desempenho teria sido inaceitável. À medida que as tecnologias mudaram, os custos práticos da compilação JIT chegaram ao ponto de serem totalmente práticos.

A resposta fica mais clara - os humanos não foram construídos para escrever programas. As máquinas devem estar fazendo isso e nos deixar relaxar jogando Pacman.

Pelo que vale a pena, li alguns trabalhos para minha aula de linguagens de computação (um de carro e outro de Nicholas Wirth) defendendo exatamente isso nos anos 60 e 70, entre outras coisas.

Não posso falar exatamente por que essas coisas não aconteceram, mas meu palpite é que é apenas uma daquelas coisas que parecem óbvias em retrospectiva que não eram óbvias na época. Não é que os compiladores anteriores não estivessem preocupados com a segurança. É que eles tinham idéias diferentes sobre como fazer isso.

Hoare menciona a idéia de um "compilador de checkout". Até onde eu sei, este é essencialmente um compilador que faz uma análise estática. Para ele, essa foi uma técnica popular que falhou (ou pelo menos não resolveu tantos problemas quanto pretendidos para resolver). A solução para ele era tornar as linguagens de programação mais seguras, criando código gerenciado (ou pelo menos é assim que ele o colocaria em termos modernos).

Eu imagino que uma vez que C (e mais tarde C ++) pegou, a idéia de código gerenciado estava essencialmente morto. Não é que C fosse um idioma ruim, apenas que se pretendia ser uma linguagem de montagem e não uma linguagem de programação de aplicativos.

Se você tiver uma chance, você pode ler Dicas sobre o design da linguagem de programação. É uma boa leitura se você estiver interessado nesse tipo de coisa.

A melhor resposta a esta pergunta é: IMHO, ninguém tinha uma idéia de código gerenciado naquele momento. O conhecimento realmente evolui com o tempo. Em comparação com campos como arquitetura ou agricultura, a ciência da computação é um campo muito jovem. Portanto, o conhecimento coletivo sobre o campo também é jovem e evoluirá com o tempo. Talvez em alguns anos nos deparemos com algum novo fenômeno e alguém fará a mesma pergunta: "Por que alguém não pensou em Xyz antes?".

Eu diria que foi amplamente resistência à mudança, juntamente com a falsa percepção da ineficiência da coleta de lixo que atrasou a adoção do GC e as técnicas relacionadas. É claro que o modelo de memória segmentado do Brain Dead no Intel 8086 não ajudou a promover exatamente o gerenciamento de memória sã no PC.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top