用 c 語言程式設計時,開發者要手工地進行記憶體管理。因為 php 經常用作 web 伺服器的模組,記憶體管理與預防記憶體洩漏緊密關聯。此外要知道 php 可能用於執行緒環境中,這意味著全域性變數可能導致競爭狀況。有關執行緒內全域性資料處理的資訊請參見作為執行緒隔離設施的 執行緒安全的資源管理器。
此外,zend 引擎要面對乙個十分特殊的使用模式:在一段比較短的時間內,許多 zval 結構大小的記憶體塊和其他的小記憶體塊被申請又再被釋放。php 的記憶體管理也很重視 memory_limit(記憶體限制)。
為了滿足以上的需求,zend 引擎提供為了處理請求相關資料提供了一種特殊的記憶體管理器。請求相關資料是指只需要服務於單個請求,最遲會在請求結束時釋放的資料。擴充套件開發者主要接觸下表中列出的慣例。雖然一些所提供的便捷功能是用巨集實現的,但在本文中會象函式一樣對待。
主要的記憶體 apis
原型說明
void *emalloc(size_t size)
分配size
位元組的記憶體。
void *ecalloc(size_t nmemb, size_t size)
給nmemb
元素分配size
位元組的緩衝區並初始化為零。
void *erealloc(void *ptr, size_t size)
修改使用emalloc
分配的緩衝區ptr
的大小為size
位元組。
void efree(void *ptr)
釋放ptr
指向的緩衝區。緩衝區必須是由emalloc
分配的。
void *safe_emalloc(size_t nmemb, size_t size, size_t offset)
分配緩衝區來存放每塊大小為size
位元組的nmemb
塊,並附加offset
位元組。類似於emalloc(nmemb * size + offset)
,但增加了針對溢位的特殊保護。
char *estrdup(const char *s)
分配乙個可存放 null 結尾的字串s
的緩衝區,並將s
複製到緩衝區內。
char *estrndup(const char *s, unsigned int length)
類似於estrdup
,但 null 結尾的字串長度是已知的。
note: 和與 c 標準庫相似的部分不同,如果分配請求的記憶體出錯,zend 引擎的記憶體管理函式不會返回 null 值,而會跳出並中止當前請求。如上所述,防止有記憶體洩漏並盡可能快地釋放所有記憶體是記憶體管理的重要組成部分。因為安全原因,在請求結束時, zend 引擎會釋放所有由上面提到的 api 所分配的記憶體。如果 php 使用
--enable-debug
配置選項進行構建,這將產生乙個警告。
example #1 php 的洩漏報警
zend_function(leak)emalloc(leakbytes);
}
以上例程的輸出類似於:
[thu oct 22 02:14:57 2009] script: '-'/home/johannes/src/php_5_3/zend/zend_builtin_functions.c(1377) : freeing 0x088888d4 (3 bytes), script=-
=== total 1 memory leaks detected ===
note: 當使用 php 變數時,需要確認變數的記憶體要使用 emalloc 來分配,並注意引用計數。相關細節請檢視 變數的使用。
note: 記憶體洩漏檢測僅可以發現由 emalloc 分配記憶體塊導致的洩漏。為進行深層分析,建議使用記憶體檢測器,如 valgrind 或 libumem 等。要簡化此分析,可在 php 啟動時通過設定環境變數 use_zend_alloc=0 來禁用 php 的記憶體管理器。
c基礎之記憶體管理
一 作用域 全域性變數和區域性變數 靜態全域性和區域性變數 總結 型別作用域 生命週期 區域性變數 int a 10 從變數定義到函式結束 區域性變數建立到函式結束 全域性變數 int a 10 整個專案檔案 程式建立到程式結束 static 區域性變數 int a 10 從變數定義到函式結束 程式...
記憶體管理之記憶體定址
記憶體定址 三種記憶體位址 邏輯位址 logical address 包含機器語言指令中用來指定乙個運算元或一條指令的位址 線性位址 linear address 線性位址也稱為虛擬位址 virtual address 實體地址 physical address 用於記憶體晶元級記憶體單元定址,他們...
c 之記憶體管理
c 使用3 種不同解決方案儲存資料,區別是資料保留在記憶體中的時間 兩種儲存持續性為自動 自動變數和暫存器變數 register 沒有記憶體位址 堆疊 在函式外定義的變數和使用關鍵字static定義的變數的儲存持續性都為靜態.分為 3 外部鏈結性,內部鏈結性和無鏈結性 所有靜態變數都有下面的兩個初始...