diff options
author | Florian Merz <me@fiji-flo.de> | 2021-02-11 14:50:24 +0100 |
---|---|---|
committer | Florian Merz <me@fiji-flo.de> | 2021-02-11 14:50:24 +0100 |
commit | 2c2df5ea01eb5cd8b9ea226b2869337e59c5fe3e (patch) | |
tree | 86ab4534d10092b293d4b7ab169fe1a8a2421bfa /files/pt-pt/web/javascript/memory_management/index.html | |
parent | 8260a606c143e6b55a467edf017a56bdcd6cba7e (diff) | |
download | translated-content-2c2df5ea01eb5cd8b9ea226b2869337e59c5fe3e.tar.gz translated-content-2c2df5ea01eb5cd8b9ea226b2869337e59c5fe3e.tar.bz2 translated-content-2c2df5ea01eb5cd8b9ea226b2869337e59c5fe3e.zip |
unslug pt-pt: move
Diffstat (limited to 'files/pt-pt/web/javascript/memory_management/index.html')
-rw-r--r-- | files/pt-pt/web/javascript/memory_management/index.html | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/files/pt-pt/web/javascript/memory_management/index.html b/files/pt-pt/web/javascript/memory_management/index.html new file mode 100644 index 0000000000..56bfec0f7f --- /dev/null +++ b/files/pt-pt/web/javascript/memory_management/index.html @@ -0,0 +1,187 @@ +--- +title: Gestão de memória +slug: Web/JavaScript/Gestao_Memoria +tags: + - Desempenho + - JavaScript + - memoria +translation_of: Web/JavaScript/Memory_Management +--- +<div>{{JsSidebar("Advanced")}}</div> + +<h2 id="Introdução">Introdução</h2> + +<p>Linguagens de baixo nível, como o C, têm funções pimitivas de gestão de memória, como por exemplo, <code>malloc()</code> e <code>free()</code>. Por outro lado, os valores em JavaScript são alocados quando coisas (objetos, variáveis de texto, etc.) são criadas e "automaticamente" libertadas da memória quando deixam de ser utilizadas. O último processo é chamado de <em>coleção do lixo</em>. Este "automatismo" é uma fonte de mal entendidos e transmite aos programadores de JavaScript ( e aos de outras linguagens de alto nível ) a impressão de que podem decidir não se preocupar com a gestão da memória. Isto é uma erro.</p> + +<h2 id="Ciclo_da_duração_da_memória">Ciclo da duração da memória</h2> + +<p>Independentemente da linguagem de programação, o ciclo da duração da memória é praticamente sempre o mesmo:</p> + +<ol> + <li>Alocação da memória necessária</li> + <li>Utilização da memória alocada ( leitura, escrita )</li> + <li>Libertar a memória alocada quando já não é necessária</li> +</ol> + +<p>A segunda etapa é explícita em todas as linguagens. A primeira e a última etapa são explícitas em linguagens de baixo nível mas são, na sua maioria, implícitas em linguagens de alto nível como o JavaScript.</p> + +<h3 id="Alocação_no_JavaScript">Alocação no JavaScript</h3> + +<h4 id="Inicialização_do_valor">Inicialização do valor</h4> + +<p>Com o intuito de não incomodar o programador com alocações, o JavaScript fá-lo juntamente com a declaração de valores.</p> + +<pre class="brush: js">var n = 123; // alocação da memória para um número +var s = 'azerty'; // alocação de memória para um texto + +var o = { + a: 1, + b: null +}; // alocação de memória para um objeto e o seu conteúdo + +// (similar ao objeto) alocação de memória para a matriz e +// os seus valores +var a = [1, null, 'abra']; + +function f(a) { + return a + 2; +} // alocação de uma função (que é um objeto que pode ser chamado) + +// Expressões de funções também alocam um objeto +someElement.addEventListener('click', function() { + someElement.style.backgroundColor = 'blue'; +}, false); +</pre> + +<h4 id="Alocação_através_de_chamadas_de_funções">Alocação através de chamadas de funções</h4> + +<p>Algumas chamadas de funções resultam na alocação de um objeto.</p> + +<pre class="brush: js">var d = new Date(); // alocação de um objeto <em>Date</em> + +var e = document.createElement('div'); // alocação de um elemento DOM</pre> + +<p>Alguns métodos alocam novos valores ou objetos:</p> + +<pre class="brush: js">var s = 'azerty'; +var s2 = s.substr(0, 3); // s2 é uma nova variável de texto +// Dado que as variáveis de texto são de valor imutável, +// o JavaScript pode decidir não alocar memória, +// mas apenas armazenar o intervalo [0, 3]. + +var a = ['ouais ouais', 'nan nan']; +var a2 = ['generation', 'nan nan']; +var a3 = a.concat(a2); +// nova matriz de 4 elementos resultando +// da concatenação dos elementos de <em>a</em> e <em>a2</em> +</pre> + +<h3 id="Utilização_de_valores">Utilização de valores</h3> + +<p>Basicamente, a utilização de valores significa a leitura e a escrita na memória alocada. Isto pode ser feito através da leitura ou escrita do valor de uma variável ou uma propriedade de um objeto ou até a passagem de um argumento para uma função.</p> + +<h3 id="Remoção_quando_a_memória_já_não_é_necessária">Remoção quando a memória já não é necessária</h3> + +<p>A maioria dos problemas de gestão de memória aparecem nesta fase. A tarefa mais difícil é descobrir quando "a memória alocada já não é necessária". Em geral, requer que o programador determine quando, no seu código, este pedaço de memória já não é necessário e a liberte.</p> + +<p>Linguagens de alto nível têm embutidas um pedaço de código chamado "coleção de lixo", cuja tarefa é rastrear a alocação e uso da memória, para detetar quando um pedaço de memória já não é necessário e neste caso, automaticamente libertá-la. Este processo é uma aproximação dado que o problema geral de se saber quando um pedaço da memória é necessário, é <a class="external" href="https://pt.wikipedia.org/wiki/Decidibilidade">indecisível</a> ( não pode ser solucionado por um algoritmo ).</p> + +<h2 id="Coleção_de_lixo">Coleção de lixo</h2> + +<p>Como mencionado anteriormente, o problema geral de automaticamente descobrir quando alguma ocupação de memória "já não é necessária", é indecisível. Como consequência, as coleções de lixo implementam uma restrição à solução para o problema em geral. Esta seção explicará as noções necessárias para se compreender os principais algoritmos da coleção de lixo e as suas limitações.</p> + +<h3 id="Referências">Referências</h3> + +<p>A noção principal dos algoritmos de coleção de lixo baseiam-se na noção de <em>referência</em>. Dentro do contexto da gestão de memória, um objeto é dito referenciar outro objeto, se o primeiro tiver acesso ao segundo ( quer implicitamente quer explicitamente ). Por exemplo, um objeto JavaScript tem uma referência ao seu <a href="https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain">protótipo</a> ( referência implícita ) e aos valores das suas propriedades ( referência explícita ).</p> + +<p>Neste contexto, a noção de "objeto" é expandida a algo mais abrangente que um objeto JavaScript e também contém âmbitos de funções ( ou âmbito léxico global ).</p> + +<h3 id="Contagem_de_referências_na_coleção_de_lixo">Contagem de referências na coleção de lixo</h3> + +<p>Este é o algoritmo mais simples da coleção de lixo. Este algoritmo reduz a definição de "um objeto já não é necessário" para "um objeto já não é referenciado por nenhum outro objeto". Um objeto é considerado coletável para a coleção de lixo se tiver nenhuma referenciação por parte de outro objeto.</p> + +<h4 id="Exemplo">Exemplo</h4> + +<pre class="brush: js">var o = { + a: { + b: 2 + } +}; +// 2 objetos criados. Um é referenciado por outro como sendo suas propriedades +// O outro é referenciado por virtude ao ser assignado para a variável 'o' +// Obviamente, nenhum podem ser coletado pela coleção de lixo + + +var o2 = o; // A variável 'o2' é a segunda coisa que + // tem uma referência ao objeto +o = 1; // agora, o objeto que era originalmente o 'o' tem uma referência única + // corporificada pela variável 'o2' + +var oa = o2.a; // referência à propriedade 'a' do objeto. + // Este objeto tem agora 2 referências: uma como propriedade, + // a outra como variável 'oa' + +o2 = 'yo'; // O objeto que era o original 'o' tem agora zero + // referências a si próprio. Pode ser coletado para a coleção de lixo + // No entanto, a propriedade 'a' ainda é referenciada pela + // variável 'oa', logo não pode ser libertado + +oa = null; // A propriedade 'a' do objeto original 'o' + // tem zero referências a si próprio. Pode ser coletado para a coleção de lixo. +</pre> + +<h4 id="Limitação_ciclos">Limitação: ciclos</h4> + +<p>Existe uma limitação no que se refere aos ciclos. No exemplo seguinte, dois objetos são criados e referenciam-se mutuamente, criando um ciclo. Estes sairão do âmbito depois de uma chamada a uma função e como tal, são efetivamente inúteis e podem ser libertados. No entanto, o algoritmo de contagem de referências considera que os dois objetos têm pelo menos uma referenciação; nenhum pode ser coletado para a coleção de lixo .</p> + +<pre class="brush: js">function f() { + var o = {}; + var o2 = {}; + o.a = o2; // o referencia o2 + o2.a = o; // o2 referencia o + + return 'azerty'; +} + +f(); +</pre> + +<h4 id="Exemplo_de_aplicação_real">Exemplo de aplicação real</h4> + +<p>O Internet Explorer 6 e 7 são conhecidos por terem um coletor de contagem de referenciações de coleções de lixo para os objetos DOM. Os ciclos são um erro comum que podem gerar percas de memória:</p> + +<pre class="brush: js">var div; +window.onload = function() { + div = document.getElementById('myDivElement'); + div.circularReference = div; + div.lotsOfData = new Array(10000).join('*'); +}; +</pre> + +<p>No exemplo acima, o elemento DOM "myDivElement" tem uma referência circular a si próprio na propriedade "circularReference". Se a propriedade não for explicitamente removida ou anulada, o coletor de contagem de referências da coleção de lixo, irá sempre ter uma referenciação intacta e irá manter o elemento DOM na memória mesmo quando for removido da árvore DOM. Se o elemento DOM contém bastante dados ( ilustrado no exemplo acima com a propriedade "lotsOfData" ), a memória consumida por estes dados nunca será libertada.</p> + +<h3 id="Algoritmo_de_marcação_e_limpeza">Algoritmo de marcação e limpeza</h3> + +<p>Este algoritmo reduz a definição de "um objeto já não é necessário" para "um objeto é inalcançável".</p> + +<p>Este algoritmo assume o conhecimento de um conjunto de objetos chamados "roots" ( em JavaScript, a <em>root</em> - raiz - é um objeto global ). Periodicamente, a coleção de lixo começará pela raíz e procurará todos os objetos que são referenciados a partir desta; depois todos os que são referenciados a partir dos seguintes, etc.. Começando pela raiz, o coletor de lixo irá localizar objetos inalcançáveis; coletando-os.</p> + +<p>Este algoritmo é melhor do que o anterior dado que "um objeto tem zero referenciações" leva a um objeto inalcançável. O contrário não é verdade como vimos nos ciclos.</p> + +<p>Desde 2012, todos os modernos navegadores de Internet contêm um coletor de marcação e limpeza. Todos os melhoramentos feitos na área da coleção de lixo no JavaScript ( generalização / incrementação / concorrência / coleção de lixo paralela ) nos últimos anos são implemetações de melhoramento deste algoritmo, mas não melhoramentos do algoritmo de coleção de lixo em si nem a sua redução à definição de que quando "um objeto já não é necessário".</p> + +<h4 id="Os_ciclos_já_não_são_um_problema.">Os ciclos já não são um problema.</h4> + +<p>No primeiro exemplo acima, depois do retorno da chamada à função, 2 objetos já não são referenciados por algo alcançável no objeto global. Consequentemente, irão ser localizados pelo coletor da coleção de lixo.</p> + +<h4 id="Limitações_os_objetos_necessitam_de_ser_explicitamente_inalcançáveis">Limitações: os objetos necessitam de ser explicitamente inalcançáveis</h4> + +<p>Apesar disto estar marcado como uma limitação, é um caso que raramente ocorre na prática pelo que é por isto que ninguém se preocupa muito com a coleção de lixo.</p> + +<h2 id="Ver_também">Ver também</h2> + +<ul> + <li><a class="external" href="http://www.ibm.com/developerworks/web/library/wa-memleak/">Aritgo da IBM sobre "Padrões de percas de memória no JavaScript" (2007)</a></li> + <li><a class="external" href="http://msdn.microsoft.com/en-us/magazine/ff728624.aspx">Artigo da Kangax sobre como registar um apontador de evento e evitar percas de memória (2010)</a></li> + <li><a href="https://developer.mozilla.org/pt-PT/docs/Mozilla/Performance" title="https://developer.mozilla.org/en-US/docs/Mozilla/Performance">Desempenho</a></li> +</ul> |