Estrutura interna de valor, referências e gerenciamento de memória no PHP \| TreinaWeb               Promoção no ar   Matricule-se agora e garanta **54% de desconto**  

  Termina em   Tempo restante da oferta: 14 Horas 

 25 Min 

 52 Seg 

   Tempo restante da oferta: 14 25 52 

  [Assinar →](https://www.treinaweb.com.br/checkout/pagamento/plano/anual?cupom=TW-SCLIENTE26) 

   [                ](https://www.treinaweb.com.br)  Explorar  

 [ Quanto custa? ](#assinatura) [ FAQ ](https://www.treinaweb.com.br#faq) [Matricule-se](#assinatura) [ Entrar ](https://www.treinaweb.com.br/login) 

     [ Início ](https://www.treinaweb.com.br) [ Artigos ](https://www.treinaweb.com.br/blog) Estrutura interna de valor, referências e gerenciamento de memória no PHP  [ PHP ](https://www.treinaweb.com.br/blog/categoria/php) 

# Estrutura interna de valor, referências e gerenciamento de memória no PHP

 Valores em PHP possuem que semântica? De valor ou de referência? Objetos são passados por referência? Essas são algumas das questões que esse artigo se propõe a responder.

 [ Kennedy Tedesco ](https://www.treinaweb.com.br/blog/autor/kennedy-tedesco) 7 anos atrás

  ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/03/04195644/php-background.jpg)  

A forma com o que o [PHP](https://www.treinaweb.com.br/blog/o-que-e-php/ "PHP") trabalha com referências e gerenciamento de memória não é um assunto muito popular e é compreensível que não seja, se levarmos em conta que na maior parte do tempo como desenvolvedores não precisamos nos preocupar com isso, ademais, o [PHP](https://www.treinaweb.com.br/blog/o-que-e-php/ "PHP") implementa um [garbage collector](https://pt.wikipedia.org/wiki/Coletor_de_lixo_(inform%C3%A1tica)) que cuida da contagem das referências e decide o melhor momento de liberar a memória, sem impactar na experiência do desenvolvedor.

Quando falo em “experiência do desenvolvedor”, me refiro ao fato de não precisarmos a todo momento usar `unset()` para destruir variáveis não mais utilizadas, tampouco passar estruturas mais complexas como objetos ou *arrays* por referência a todo momento etc. Há raros e específicos casos em que usar referência faz sentido. Como também há raros e específicos casos em que liberar a memória manualmente (sem aguardar o trabalho do *garbage collector*) faz sentido como, por exemplo, a liberação de um `resource` para alguma operação subsequente importante que vai consumir um tanto considerável de memória.

A ideia aqui é tentar ao máximo ter uma abordagem leve, de desenvolvedor para desenvolvedor, no sentido de usuários da linguagem. Não tenho a pretenção e nem o conhecimento necessário para explicar o funcionamento interno do PHP e, além do mais, existe gente muito boa e mais preparada pra isso (compartilharei links no final do artigo).

Em suma, esse artigo se propõe a responder as seguintes questões:

- Como um valor é representado internamente no PHP?
- Valores em PHP possuem que semântica? De valor ou de referência?
- Referências? O que são?
- Objetos são passados por referência?
- Se tenho um array com milhões de registros e preciso passá-lo para o argumento de uma função, e agora? Vou dobrar o tanto de memória que estou usando?

[  ![PHP - Fundamentos](https://d2knvm16wkt3ia.cloudfront.net/assets/svg-icon/php.svg)   Curso PHP - Fundamentos Conhecer o curso ](https://www.treinaweb.com.br/curso/php-fundamentos)

**A estrutura de dado que representa os valores do PHP**

No PHP existe uma estrutura de dado elementar chamada *zval* (zend value), ela é uma estrutura *container* para qualquer valor arbitrário que se trabalha no PHP:

```c
struct _zval_struct {
	zend_value value;
	union {
        // ...
		uint32_t type_info;
	} u1;
    // ...
};

```

Para a nossa noção, o mais importante é notarmos que essa estrutura armazena o valor e o tipo desse valor. E, pelo fato de o PHP ser uma [linguagem de tipagem dinâmica](https://www.treinaweb.com.br/blog/tipos-no-php/ "linguagem de tipagem dinâmica"), o tipo é conhecido apenas em tempo de execução e não em tempo de compilação. Além disso, esse tipo pode mudar durante a execução, por exemplo, um inteiro pode simplesmente virar uma string em um dado momento.

O valor propriamente dito é armazenado na union *zend\_value* (uma union define múltiplos membros de diferentes tipos mas só um deles pode ser ativo por vez):

```c
typedef union _zend_value {
	zend_long         lval;				/* long value */
	double            dval;				/* double value */
	zend_refcounted  *counted;
	zend_string      *str;
	zend_array       *arr;
	zend_object      *obj;
	zend_resource    *res;
	zend_reference   *ref;
	zend_ast_ref     *ast;
	zval             *zv;
	void             *ptr;
	zend_class_entry *ce;
	zend_function    *func;
	struct {
		uint32_t w1;
		uint32_t w2;
	} ww;
} zend_value;

```

Por essa estrutura já podemos inferir os tipos internos das variáveis que declaramos. Objetos são armazenados numa estrutura separada do tipo `zend_object`, arrays são do tipo `zend_array` numa implementação de [HashTable](https://pt.wikipedia.org/wiki/Tabela_de_dispers%C3%A3o) e assim por diante. Valores simples como inteiros e float são armazenados diretamente na zval, enquanto que valores complexos como strings e objetos são armazenados em estruturas separadas e representados na zval por ponteiros (como pode ser visto em `zend_string *str;`).

Outra noção refere-se ao fato de que internamente o PHP faz a contagem da quantidade de vezes que um valor é usado por outras variáveis (*symbols*) e isso é essencial para o gerenciamento da memória por parte do *garbage collector*, uma vez que esse contador estiver zerado, indica pro GC que a memória desse valor pode ser liberada.

**A semântica dos valores**

No PHP os valores possuem a semântica de *valor*, desde que explicitamente não peçamos por uma referência. Ou seja, quando passamos um valor para um argumento de uma função, ou quando atribuímos uma variável a outra, estamos sempre trabalhando em cópias do mesmo valor. Vamos esclarecer esse conceito com exemplos, para que depois possamos adentrar no assunto de referências.

Exemplo:

```php
