PHP變量管理(銷毀,分配)是基于引用計數和寫時復制實現的
### 引用計數
  php垃圾回收使用來引用計數的方法,php變量由zval結構體維護,zval結構體有refcount表示有多少個變量指向這個zval容器,is_ref用于區分引用變量,當unset一個變量時,會端斷開變量到內存區域的鏈接,同時講該區域的refcount引用計數減1,當refcount為0時,被當做垃圾,釋放內存
引用計數的信息位于給具體value結構的gc中:
```c
typedef struct _zend_refcounted_h {
uint32_t refcount; /* reference counter 32-bit */
union {
struct {
ZEND_ENDIAN_LOHI_3(
zend_uchar type,
zend_uchar flags, /* used for strings & objects */
uint16_t gc_info) /* keeps GC root number (or 0) and color */
} v;
uint32_t type_info;
} u;
} zend_refcounted_h;
```
note: 并不是所有的數據類型都會用到引用計數,如long、double直接都是硬拷貝,[參考](http://www.hmoore.net/nickbai/php7/363267)
### 寫時復制
  變量復制、函數傳參時并不直接硬拷貝一份value數據,而是將refcount++,變量銷毀時將refcount--,等到refcount減為0時表示已經沒有變量引用這個value,將它銷毀;如果其中一個變量試圖更改value的內容則會重新拷貝一份value修改,同時斷開舊的指向,并且refcount--
### 內存溢出問題
  php5.3版本之前會有內存溢出,主要是環形引用的問題(環形引用舉個例子:數組一個元素的值復制為該數組的引用);這種問題主要出現在array,object兩種類型
gc機制:當refcount減1時,如果不為0且類型是IS_ARRAY、IS_OBJECT,則添加到回收池,當回收池滿了,會遍歷所有變量以及變量下面每一項,模擬recount減1,如果變量整個refcount為0,表示為垃圾,可以回收
### unset函數
  unset只是斷開一個變量到一塊內存區域的鏈接,同時將該區域的引用計數-1,內存是否回收主要看refcount是否為0
### 參考
- 《PHP7內核剖析》
- [php7 垃圾回收機制詳解](https://segmentfault.com/a/1190000016240169)
- php
- 編譯安裝
- 基本概念
- 垃圾回收機制
- 生命周期
- zval底層實現
- c擴展開發
- gdb調試工具
- 自定義擴展簡單demo
- 鉤子函數
- 讀取php.ini配置
- 數組
- 函數
- 類
- yaf擴展底層源碼
- swoole擴展底層源碼
- memoryGlobal內存池
- swoole協程使用記錄
- 單點登錄sso原理
- compser使用
- session實現機制
- c & linux
- gcc
- 指針
- 結構體,聯合和位字段
- 宏定義井號說明
- printf家族函數和可變參數
- 共享函數
- 靜態庫和動態庫
- makefile自動化構建
- 信號一
- 信號二
- inotify監控文件事件
- socket編程
- 簡介
- UNIX DOMAIN
- Internet DOMAIN
- TCP/IP
- 文件IO多路復用
- 內存管理
- 進程組,會話和控制終端
- daemon守護進程
- 多進程
- 多線程
- 常用進制轉換
- go
- 入門知識
- 字節和整數裝換
- python
- redis
- 應用場景
- 消息隊列
- 熱點數據
- 掃碼登錄
- 訂閱發布
- 次數限制
- 搶購超賣
- 持久化機制
- mysql
- 工作流程
- MyISAM和InnoDB區別
- 用戶和權限管理
- 執行計劃
- sql優化
- 事務和鎖
- 慢查詢日志
- case...when...then...end用法
- sql
- 參考
- linux
- 內核參數優化
- 防火墻設置
- docker
- docker入門知識
- 算法
- 多維數組合
- DFA算法
- 紅包金額分配