1. Mecanismo de reciclagem de lixo - GC
O JavaScript possui um mecanismo automático de coleta de lixo (GC: coleta de lixo), o que significa que o ambiente de execução é responsável por gerenciar a memória usada durante a execução do código.
Princípio: O coletor de lixo periodicamente (periódico) encontra variáveis que não estão em uso e depois libera sua memória.
O mecanismo da coleção de lixo JavaScript é muito simples: descubra variáveis que não são mais usadas e liberam a memória que ocupa. No entanto, esse processo não é em tempo real porque sua sobrecarga é relativamente grande, portanto o coletor de lixo será executado periodicamente em intervalos de tempo fixo .
Variáveis que não são mais usadas são variáveis que terminam o ciclo de vida. Obviamente, eles só podem ser variáveis locais. O ciclo de vida da variável global não terminará até que o navegador desinstale a página. As variáveis locais existem apenas durante a execução da função e, nesse processo, o espaço correspondente será alocado para variáveis locais na pilha ou pilhagem para armazenar seus valores e, em seguida, essas variáveis são usadas na função até o final da função. No entanto, devido a funções internas no fechamento, as funções externas não podem ser consideradas terminando.
Vamos apenas explicar o código:
função fn1 () {var obj = {name: 'hanzichi', idade: 10};} função fn2 () {var obj = {name: 'hanzichi', idade: 10}; retornar obj;} var a = fn1 (); var b = fn2 ();Vamos ver como o código é executado. Primeiro, duas funções são definidas, chamadas FN1 e FN2. Quando o FN1 é chamado, a entrada no ambiente FN1 abrirá um objeto de armazenamento de memória {Nome: 'Hanzichi', idade: 10}. Quando a chamada é concluída e o ambiente FN1 terminar, o bloco de memória será lançado automaticamente pelo coletor de lixo no motor JS; Durante o processo de que o FN2 está sendo chamado, o objeto retornado é apontado pela variável global B, para que o bloco de memória não seja liberado.
Aqui surge a pergunta: qual variável é inútil? Portanto, o coletor de lixo deve rastrear qual variável é inútil e marca variáveis que não são mais úteis para recuperar sua memória no futuro. As estratégias para variáveis inúteis usadas para marcar podem diferir pela implementação, e geralmente há duas maneiras de fazer isso: marcar a liberação e a contagem de referência. A contagem da citação não é muito comum, a limpeza de marcas é mais comumente usada.
2. Marca clara
O método de coleta de lixo mais usado em JS é a remoção de marcas. Quando uma variável entra no ambiente, por exemplo, declara uma variável em uma função, ela marca a variável como "Entre no ambiente". Logicamente falando, a memória ocupada por variáveis que entra no ambiente não pode ser liberada, porque elas podem ser usadas desde que o fluxo de execução entre no ambiente correspondente. E quando uma variável sai do meio ambiente, ela é marcada como "fora do meio ambiente".
function test () {var a = 10; // está marcado, digite o ambiente var b = 20; // está marcado, digite o ambiente} test (); // Após a execução, A e B são marcados, deixam o meio ambiente e são reciclados.Quando o coletor de lixo é executado, marca todas as variáveis armazenadas na memória (é claro, qualquer método de marcação pode ser usado). Em seguida, ele remove as tags (fechamentos) de variáveis no ambiente e variáveis referenciadas por variáveis no ambiente. As variáveis marcadas após isso serão consideradas como variáveis prontas para serem excluídas porque as variáveis no ambiente não podem mais acessar essas variáveis. Finalmente, o coletor de lixo completa o trabalho de limpeza da memória, destruindo esses valores marcados e recuperando o espaço de memória que eles ocupam.
Até agora, as implementações do JS de IE, Firefox, Opera, Chrome e Safari usam estratégias de coleta de lixo com limpeza de marcas ou estratégias semelhantes, mas os intervalos de tempo da coleta de lixo são diferentes um do outro.
3. Contagem de cotação
O significado da contagem de referência é acompanhar o número de vezes que cada valor é referenciado. When a variable is declared and a reference type value is assigned to the variable, the number of references to this value is 1. If the same value is assigned to another variable, the number of references to the value is increased by 1. On the contrary, if the variable containing the reference to this value takes another value, the number of references to this value is reduced by 1. When the number of references to this value becomes 0, it means that there is no way to access the value again, so the memory O espaço que ocupa pode ser recuperado. Dessa forma, quando o coletor de lixo é executado novamente na próxima vez, libera a memória que valoriza com 0 referências.
function test () {var a = {}; // O número de referências de A é 0 var B = a; // o número de referências de A é 1 var c = a; // o número de referências de A é 1 e o número de referências de A é 1 e o número de referências de A IS 1, e o número de referências de A é 2 var B = {}; // O número de referências de A é 1 e o número de referências de A é 1}O Netscape Navigator3 foi o primeiro navegador a usar a estratégia de contagem de referência, mas logo encontrou um problema sério: referências circulares. Uma referência circular refere -se a um objeto A contendo um ponteiro ao objeto B, e o objeto B também contém uma referência ao objeto A.
função fn () {var a = {}; var b = {}; a.pro = b; b.pro = a;} fn ();Os tempos de referência de A e B acima estão 2. Depois que Fn () é executado, ambos os objetos deixaram o ambiente. Não há problema no modo de limpeza de marcas. No entanto, sob a estratégia de contagem de referência, porque os tempos de referência de A e B não são 0, a memória não será coletada pelo coletor de lixo. Se a função FN for chamada em grandes quantidades, ocorrerá vazamento de memória. No IE7 e IE8, a memória aumenta bruscamente.
Sabemos que alguns objetos no IE não são objetos JS nativos. Por exemplo, os objetos no DOM e no BOM são implementados na forma de objetos COM usando C ++, e o mecanismo de coleta de lixo dos objetos COM adota uma estratégia de contagem de referência. Portanto, mesmo que o mecanismo JS do IE adote uma estratégia de limpeza de tags, os objetos COM acessados pelo JS ainda se baseiam na estratégia de contagem de referência. Em outras palavras, desde que os objetos COM estejam envolvidos no IE, haverá um problema de referências circulares.
var elemento = document.getElementById ("Some_Element"); var myObject = new Object (); myObject.e = element; element.o = myObject;Este exemplo cria uma referência circular entre um elemento DOM e um objeto JS nativo. Entre eles, o MyObject variável possui um atributo chamado elemento apontando para o objeto elemento; e o elemento variável também possui um atributo chamado O de volta para se referir ao MyObject. Devido a essa referência circular, mesmo que o DOM no exemplo seja removido da página, ele nunca será reciclado.
Olhando para o exemplo acima, alguns estudantes pensaram que era muito fraco. Quem faria uma coisa tão chata? Na verdade, estamos fazendo isso?
window.onLoad = função ExterFunction () {var obj = document.getElementById ("elemento"); obj.OnClick = function inerfunction () {};};Esse código parece estar bem, mas OBJ refere -se ao documento.getElementById ("Element"), e o método onclick do document.getElementById ("elemento") se referirá à variável alemã no ambiente externo, que naturalmente também inclui OBJ. Não está muito escondido?
Solução
A maneira mais fácil é a não referência manualmente o loop, por exemplo, a função agora pode fazer isso.
myObject.Element = null; element.o = null;
window.onLoad = função ExterFunction () {var obj = document.getElementById ("elemento"); obj.OnClick = function inerfunction () {}; obj = null;};Definir uma variável para nulo significa cortar a conexão entre a variável e o valor que ela referenciou anteriormente. Quando o coletor de lixo é executado na próxima vez, esses valores são excluídos e a memória que eles ocupam é reciclada.
Deve -se notar que o IE9+ não tem uma referência circular para causar vazamentos de memória DOM. Pode ser que a Microsoft o otimizasse ou o método de reciclagem de Dom mudou.
4. Gerenciamento de memória
1. Quando a coleta de lixo será acionada?
O coletor de lixo funciona periodicamente. Se a memória alocada for muito grande, o trabalho de reciclagem será muito difícil. Determinar o intervalo de tempo de coleta de lixo se torna uma questão que vale a pena pensar. A coleção de lixo do IE6 é executada de acordo com a alocação de memória. Quando houver 256 variáveis, 4096 objetos e strings de 64 mil no ambiente, o coletor de lixo será acionado. Parece muito científico e não precisa ser chamado de vez em quando. Às vezes é desnecessário. Não é bom chamar sob demanda assim? Mas se houver tantas variáveis no ambiente, e os scripts são tão complexos e normais agora, o resultado é que o coletor de lixo está sempre funcionando, para que o navegador não possa jogar.
A Microsoft fez ajustes no IE7. As condições do gatilho não são mais fixas, mas modificadas dinamicamente. O valor inicial é o mesmo que IE6. Se a alocação de memória coletada pelo coletor de lixo for inferior a 15% da memória ocupada pelo programa, isso significa que a maior parte da memória não pode ser reciclada. As condições de gatilho de coleta de lixo definidas são muito sensíveis. Neste momento, duplique as condições da rua. Se a memória coletada for superior a 85%, significa que a maior parte da memória deve ser limpa há muito tempo. No momento, as condições de gatilho são reduzidas. Isso faz com que a reciclagem de lixo funcione mais funções
2. Solução GC razoável
1) A solução GC básica do mecanismo JavaScript é (simples GC): Mark and Sweep, isto é:
2) Defeitos de GC
Como outros idiomas, a política do GC do JavaScript não pode evitar um problema: ao GC, pare de responder a outras operações, que é por razões de segurança. O GC do JavaScript é 100ms ou até acima, o que é bom para aplicações gerais, mas para jogos JS, aplicativos que exigem alta coerência são problemáticos. É isso que o novo mecanismo precisa otimizar: Evite a resposta a longo prazo causada pelo GC.
3) Estratégia de otimização do GC
O tio David introduziu principalmente duas soluções de otimização, e essas também são as duas soluções de otimização mais importantes:
(1) geração gc)
Isso é consistente com a idéia da estratégia de reciclagem Java. O objetivo é distinguir objetos "temporários" e "persistentes"; Recicle mais áreas de "objeto temporário" e menos áreas de objetos titulares ", reduza os objetos que precisam ser percorridos a cada vez, reduzindo assim o tempo gasto em GCs a cada vez. Como mostrado na imagem:
O que precisa ser adicionado aqui é que, para o objeto de geração titular, há uma sobrecarga adicional: migre -o da geração jovem para a geração titular e, se for referenciada, a referência também precisa ser modificada.
(2) GC incremental
A idéia desse plano é muito simples, que é "tratar um pouco a cada vez, lidar um pouco da próxima vez e assim por diante". Como mostrado na imagem:
Embora essa solução demore pouco, ela possui muitas interrupções, o que traz o problema da comutação frequente de contexto.
Como cada solução possui seus cenários e desvantagens aplicáveis, em aplicações reais, a solução será selecionada de acordo com a situação real.
Por exemplo: quando a relação (objeto/s) é baixa, a frequência da execução do GC é interrompida e o GC simples é menor; Se um grande número de objetos for "sobrevivido" por um longo tempo, a vantagem do processamento geracional não é grande.
O artigo acima entende de forma abrangente que o mecanismo de reciclagem de coleta de lixo do JavaScirp é todo o conteúdo que compartilho com você. Espero que possa lhe dar uma referência e espero que você possa apoiar mais o wulin.com.