php原始碼02 -基本變數與記憶體管理機制
概述
這是原始碼php7系列的第二篇文章,主要介紹變數的機制和記憶體的管理,我相信學習原始碼是對程式碼整體提升的有效手段,話不多說,開始吧!
php7編譯安轉、新特性
變數實現
1. 解密zval
zval 底層結構:
struct_zval_struct {
zend_value value; //8個位元組
union u1; //4個位元組
union u2; //4個位元組
}
1
2
3
4
5
對於vue來說是一個聯合體,zval一共16個位元組,u1 4個位元組,u2四個位元組,value結構體如下:
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;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
雖然PHP屬於弱型別語言,但是在底層實現中還是要區分型別的,因為型別裡有天然的長度,型別引勢記憶體的長度。
底層做了很多型別轉化的處理,讓我們不用關心php的型別和長度,這也是php開發高效的原因之一。
變數知識點:
value、u1、u2都是聯合體,在底層是要區分型別的
u2裡面有個重要的變數next,next會在陣列中解決衝突使用
2.寫時複製(Copy On Write)
struct _zend_string {
zend_refcounted_h gc;
zend_ulong h; /* hash value */
size_t len;
char val[1];
};
1
2
3
4
5
6
zend_refcounted_h 作用是string型別的引用計數的結構體,h是字串對應的hash值,它後面會用到陣列裡,len代表字串的長度,char是字串的值,因為C言語中字串遇到\0就會自動結束,二進位制是不安全的,所以php加上了長度。
$value1 = 'stark';
$value2 = $value1;
$value2 = 'zcc';
1
2
3
php的寫時複製是這樣發生的,如果把v a l u e 1 賦 值 給 value1賦值給value1賦值給value2,兩個變數指向的是同一個實體記憶體地址,存在硬碟上的某一個塊裡,也許地址是0x7fff5e01c00,當$value2賦值新的值時,zend_refcounted_h引用計數減一,zcc存入新的地址。可以看我之前的文章。
3.字串的引用型別
struct _zend_reference {
zend_refcounted_h gc;
zval val;
};
1
2
3
4
可以跟著程式碼執行一下,看看你心裡的預期和實際列印出的值是否一致
$a = 'hello';
$b = &$a;
var_dump($a,$b);
$b = 'stark';
var_dump($a,$b);
unset($b);
var_dump($a,$b);
1
2
3
4
5
6
7
8
9
執行結果:
[root@dd2065d03db8 code]# /usr/local/php7.1.0/bin/php refer.php
string(5) "hello"
string(5) "hello"
string(5) "stark"
string(5) "stark"
string(5) "stark"
NULL
1
2
3
4
5
6
7
原始碼中的陣列HashTable
struct _zend_array {
zend_refcounted_h gc;
union {
struct {
ZEND_ENDIAN_LOHI_4(
zend_uchar flags,
zend_uchar nApplyCount,
zend_uchar nIteratorsCount,
zend_uchar consistency)
} v;
uint32_t flags;
} u;
uint32_t nTableMask;
Bucket *arData;
uint32_t nNumUsed;
uint32_t nNumOfElements;
uint32_t nTableSize;
uint32_t nInternalPointer;
zend_long nNextFreeElement;
dtor_func_t pDestructor;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
nTableMask是計算陣列的索引值,*arData儲存陣列裡的key=>value的鍵值對,nNumUsed表示已經使用的空間,nNumOfElements真正的元素個數,nTableSize是arData的大小,nTableSize預設大小是8位元組,記憶體不夠每次擴容都x2,以此類推。
記憶體管理
在malloc申請記憶體時宣告瞭size大小,但是回收時沒有傳size,怎麼做到準確釋放size大小記憶體的呢?
void *ptr=malloc(size);
free(ptr);
1
2
php7記憶體介面
void *ptr=_emalloc(size);
_efree(ptr);
1
2
1.Small記憶體的管理
記憶體的基本概念:chunk、page、各種規格的記憶體。
chunk: 2MB 大小的記憶體
page :4KB大小的記憶體
#define ZEND_MM_CHUNK_SIZE (2 * 1024 * 1024) /* 2 MB */
#define ZEND_MM_PAGE_SIZE (4 * 1024) /* 4 KB */
#define ZEND_MM_PAGES (ZEND_MM_CHUNK_SIZE / ZEND_MM_PAGE_SIZE) /* 512 */
1
2
3
記憶體規格
記憶體預分配:使用mmap分配chunk
記憶體分類:
1.Small(30種規格) (size <= 3KB)
2.Large (3KB < size <= 2MB-4KB)
3.Huge(size > 2MB-4KB)
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70010128/viewspace-2871664/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Python記憶體管理機制-《原始碼解析》Python記憶體原始碼
- android記憶體管理機制與優化Android記憶體優化
- Java記憶體管理機制Java記憶體
- jvm記憶體管理機制JVM記憶體
- javaScript 記憶體管理機制JavaScript記憶體
- 淺析java記憶體管理機制Java記憶體
- 記憶體管理機制的發展記憶體
- 【記憶體管理】頁面分配機制記憶體
- PHP 垃圾回收與記憶體管理指引PHP記憶體
- Android彈藥庫——記憶體管理機制與程式模型Android記憶體模型
- Memcached記憶體管理原始碼分析記憶體原始碼
- Python如何管理記憶體?記憶體分配機制是什麼?Python記憶體
- C++動態記憶體管理與原始碼剖析C++記憶體原始碼
- 變數、作用域與記憶體變數記憶體
- Python記憶體管理:基本概念與技巧Python記憶體
- JVM自動記憶體管理機制 二JVM記憶體
- Java的記憶體管理機制之記憶體區域劃分Java記憶體
- javascript的垃圾回收機制和記憶體管理JavaScript記憶體
- 一文洞悉JVM記憶體管理機制JVM記憶體
- 深度學習 Caffe 記憶體管理機制理解深度學習記憶體
- Objective-C中的記憶體管理機制Object記憶體
- 垃圾收集機制與記憶體分配策略記憶體
- Paddle原始碼之記憶體管理技術原始碼記憶體
- Go:記憶體管理與記憶體清理Go記憶體
- java基礎(一):談談java記憶體管理與垃圾回收機制Java記憶體
- V8記憶體管理及垃圾回收機制記憶體
- 80386分頁機制與虛擬記憶體記憶體
- 02. Rust 記憶體管理 Copy & Clone(上)Rust記憶體
- js記憶體回收機制JS記憶體
- Flutter引擎原始碼解讀-記憶體管理篇Flutter原始碼記憶體
- Netty原始碼解析 -- 記憶體池與PoolArenaNetty原始碼記憶體
- [譯] 通過垃圾回收機制理解 JavaScript 記憶體管理JavaScript記憶體
- 要點提煉| 理解JVM之記憶體管理機制JVM記憶體
- spark 原始碼分析之十五 -- Spark記憶體管理剖析Spark原始碼記憶體
- AntDB記憶體管理之記憶體上下文之記憶體上下文機制是怎麼實現的記憶體
- 記憶體管理 記憶體管理概述記憶體
- JVM 自動記憶體管理機制及 GC 演算法JVM記憶體GC演算法
- jvm:記憶體模型、記憶體分配及GC垃圾回收機制JVM記憶體模型GC