<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/book.mysqlnd.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'pt_BR',
  ),
  'this' => 
  array (
    0 => 'mysqlnd.memory.php',
    1 => 'Gerenciamento de Mem&oacute;ria',
    2 => 'Gerenciamento de Mem&oacute;ria',
  ),
  'up' => 
  array (
    0 => 'book.mysqlnd.php',
    1 => 'Mysqlnd',
  ),
  'prev' => 
  array (
    0 => 'mysqlnd.notes.php',
    1 => 'Notas',
  ),
  'next' => 
  array (
    0 => 'mysqlnd.plugin.php',
    1 => 'API do plugin do Driver Nativo MySQL',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'pt_BR',
    'path' => 'reference/mysqlnd/memory.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="mysqlnd.memory" class="chapter">
 <h1 class="title">Gerenciamento de Memória</h1>

 <p class="simpara">
  <strong>Introdução</strong>
 </p>
 <p class="simpara">
  O Driver Nativo MySQL gerencia memória diferente da Biblioteca Cliente MySQL.
  As bibliotecas diferem na forma como a memória é alocada e liberada,
  como a memória é alocada em pedaços durante a leitura dos resultados do MySQL, quais opções
  de depuração e desenvolvimento existem e como os resultados lidos do MySQL são vinculados
  às variáveis ​​de usuário do PHP.
 </p>
 <p class="simpara">
  As notas a seguir pretendem ser uma introdução e um resumo aos usuários
  interessados ​​em compreender o Driver Nativo MySQL em nível de código C.
 </p>
 <p class="simpara">
  <strong>Funções de gerenciamento de memória usadas</strong>
 </p>
 <p class="simpara">
  Toda a alocação e desalocação de memória é feita usando as funções de gerenciamento
  de memória do PHP. Portanto, o consumo de memória do mysqlnd pode ser rastreado
  usando chamadas de API PHP, como <span class="function"><a href="function.memory-get-usage.php" class="function">memory_get_usage()</a></span>. Como a memória
  é alocada e liberada usando o gerenciamento de memória do PHP, as alterações podem não
  se tornar imediatamente visíveis no nível do sistema operacional. O gerenciamento
  de memória do PHP atua como um proxy que pode atrasar a liberação de memória para
  o sistema. Devido a isso, é difícil comparar o uso de memória do Driver Nativo MySQL
  e da Biblioteca Cliente MySQL. A Biblioteca Cliente MySQL
  está usando as chamadas de gerenciamento de memória do sistema operacional diretamente, portanto, os
  efeitos podem ser observados imediatamente no nível do sistema operacional.
 </p>
 <p class="simpara">
  Qualquer limite de memória imposto pelo PHP também afeta o Driver Nativo MySQL. Isso
  pode causar erros de falta de memória ao buscar conjuntos de resultados grandes que excedem
  o tamanho da memória restante disponibilizada pelo PHP. Como a Biblioteca Cliente MySQL
  não usa funções de gerenciamento de memória PHP, ela não está em conformidade
  com nenhum limite de memória PHP definido. Se estiver usando a Biblioteca Cliente MySQL, dependendo do
  modelo de implantação, o consumo de memória do processo PHP pode crescer
  além do limite de memória do PHP. Mas também os scripts PHP podem processar conjuntos
  de resultados maiores, pois partes da memória alocada para armazenar os conjuntos de resultados estão além
  do controle do mecanismo PHP.
 </p>
 <p class="simpara">
   As funções de gerenciamento de memória do PHP são invocadas pelo Driver Nativo MySQL através
   de um encapsulador leve. Entre outros, o encapsulador facilita a depuração.
 </p>
 <p class="simpara">
   <strong>Lidando com conjuntos de resultados</strong>
 </p>
 <p class="simpara">
  Os vários servidores MySQL e as diversas APIs do cliente diferenciam
  entre conjuntos de resultados <a href="mysqli.quickstart.statements.php" class="link">com buffer e sem buffer</a>.
  Conjuntos de resultados sem buffer são transferidos linha por linha do MySQL para o cliente
  à medida que o cliente itera sobre os resultados. Os resultados armazenados em buffer são buscados
  integralmente pela biblioteca cliente antes de serem repassados ​​ao cliente.
 </p>
 <p class="simpara">
  O Driver Nativo MySQL está utilizando fluxos PHP para a comunicação da rede
  com o Servidor MySQL. Os resultados enviados pelo MySQL são buscados dos buffers da
  rede de fluxos do PHP para o buffer de resultados do mysqlnd. O buffer resultante é
  composto de zvals. Numa segunda etapa os resultados são disponibilizados para o script PHP.
  Esta transferência final do buffer de resultados para variáveis ​​PHP impacta o consumo de memória
  e é principalmente perceptível ao usar conjuntos de resultados armazenados em buffer.
 </p>
 <p class="simpara">
  Por padrão o Driver Nativo MySQL tenta evitar armazenar
  resultados em buffer duas vezes na memória. Os resultados são mantidos apenas uma vez nos buffers
  de resultados internos e seus zvals. Quando os resultados são buscados em variáveis ​​PHP
  pelo script PHP, as variáveis ​​farão referência aos buffers de resultados internos.
  Os resultados da consulta ao banco de dados não são copiados e mantidos na memória apenas uma vez.
  Caso o usuário modifique o conteúdo de uma variável que contém os resultados do banco de dados,
  uma cópia na gravação deverá ser executada para evitar a alteração do buffer de resultados interno
  referenciado. O conteúdo do buffer não deve ser modificado porque o usuário
  pode decidir ler o conjunto de resultados uma segunda vez. O mecanismo de cópia na gravação
  é implementado usando uma lista de gerenciamento de referência
  adicional e o uso de contadores de referência zval padrão.
  A cópia na gravação também deve ser feita se o usuário ler um conjunto de resultados em variáveis ​​PHP
  e liberar um conjunto de resultados antes que as variáveis ​​sejam desdefinidas.
 </p>
 <p class="simpara">
  De modo geral, esse padrão funciona bem para scripts que leem um conjunto
  de resultados uma vez e não modificam variáveis ​​que contêm resultados. Sua principal desvantagem
  é a sobrecarga de memória causada pelo gerenciamento de referência adicional que
  vem principalmente do fato de que as variáveis ​​do usuário que contêm resultados
  não podem ser totalmente liberadas até que o gerenciamento de referência do mysqlnd
  pare de referenciá-las. O Driver Nativo MySQL remove a referência às
  variáveis ​​do usuário quando o conjunto de resultados é liberado ou uma cópia na gravação é executada.
  Um observador verá o consumo total de memória crescer até que o conjunto de resultados
  seja liberado. Use as <a href="mysqlnd.stats.php" class="link">estatísticas</a> para verificar
  se um script libera conjuntos de resultados explicitamente ou se o driver faz liberações
  implícitas e, portanto, a memória é usada por um tempo maior que o necessário. As estatísticas
  também ajudam a ver quantas operações de cópia na gravação ocorreram.
 </p>
 <p class="simpara">
  Um script PHP lendo muitas linhas pequenas de um conjunto de resultados em buffer usando um trecho de código
  igual ou equivalente a <code class="literal">while ($row = $res-&gt;fetch_assoc()) { ... }</code>
  pode otimizar o consumo de memória solicitando cópias em vez de referências.
  Embora solicitar cópias signifique manter os resultados duas vezes na memória, isso permite
  que o PHP libere a cópia contida em <code class="literal">$row</code> à medida que o conjunto de resultados
  está sendo iterado e antes de liberar o próprio conjunto de resultados. Em um servidor carregado,
  a otimização do uso máximo de memória pode ajudar a melhorar o desempenho geral do sistema,
  embora para um script individual a abordagem de cópia possa ser mais lenta devido a
  alocações adicionais e operações de cópia de memória.
 </p>
 <p class="simpara">
   <strong>Monitoramento e depuração</strong>
 </p>
 <p class="simpara">
  Existem diversas formas de rastrear o uso de memória do Driver Nativo MySQL.
  Se o objetivo é obter uma visão geral rápida de alto nível ou verificar a eficiência da memória
  dos scripts PHP, então verifique as <a href="mysqlnd.stats.php" class="link">estatísticas</a>
  coletadas pela biblioteca. As estatísticas permitem, por exemplo, capturar
  instruções SQL que geram mais resultados do que são processados ​​por um script PHP.
 </p>
 <p class="simpara">
  O log de rastreamento <a href="mysqlnd.config.php#ini.mysqlnd.debug" class="link">debug</a> pode ser configurado para
  registrar chamadas de gerenciamento de memória. Isso ajuda a ver quando a memória está alocada
  ou liberada. No entanto, o tamanho dos blocos de memória solicitados pode não estar listado.
 </p>
 <p class="simpara">
  Algumas versões recentes do Driver Nativo MySQL apresentam a emulação de
  situações aleatórias de falta de memória. Este recurso deve ser usado apenas pelos
  desenvolvedores C da biblioteca ou pelos autores do <a href="mysqlnd.plugin.php" class="link">plugin</a>
  do mysqlnd. Por favor, pesquise no código-fonte as configurações correspondentes do PHP
  e mais detalhes. O recurso é considerado privado e pode ser
  modificado a qualquer momento sem aviso prévio.
 </p>

</div>
<?php manual_footer($setup); ?>