本篇文章给大家带来的内容是关于php中small内存规格的计算(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。
small内存分配计算bin_num
在PHP源码中,有一段对small内存规格的计算,具体在Zend/zend_alloc.c的zend_mm_small_size_to_bin函数中,其目的是传入一个size,计算对应的规格。见代码:
if (size <= 64) { /* we need to support size == 0 ... */ return (size - !!size) >> 3; } else { t1 = size - 1; t2 = zend_mm_small_size_to_bit(t1) - 3; t1 = t1 >> t2; t2 = t2 - 3; t2 = t2 << 2; return (int)(t1 + t2); }
可以看出,这段代码中分为两种情况进行讨论:
1、size小于等于64的情况;
2、size大于64的情况;
下面我们对这两种情况详细分析下。
对于size小于等于64的情况
看
ZEND_MM_BINS_INFO
这个宏知道当size小于等于64的情况是一个等差数列,递增8,所以使用size除以8就行(源码中是右移3位)size >> 3</pre> <li><p>但是要考虑到size等于8、16等的情况,所以为 <code>(size - 1) >> 3
然后要考虑到为0的情况,所以源码中对于
-1
的处理是!!size
,当size为0的情况!!0 = 0
。所以当size为0的情况就把-1
转换成了-0
,最终有了源码中的表达式(size - !!size) >> 3
对于size大于64的情况
t1 = size - 1; t2 = zend_mm_small_size_to_bit(t1) - 3; t1 = t1 >> t2; t2 = t2 - 3; t2 = t2 << 2; return (int)(t1 + t2);
初始懵逼
初看这个代码,容易一脸懵逼,这些t1 t2 都是啥啊
不过不用怕,我们一点点来分析
步骤分析
/* num, size, count, pages */ #define ZEND_MM_BINS_INFO(_, x, y) \ _( 0, 8, 512, 1, x, y) \ _( 1, 16, 256, 1, x, y) \ _( 2, 24, 170, 1, x, y) \ _( 3, 32, 128, 1, x, y) \ _( 4, 40, 102, 1, x, y) \ _( 5, 48, 85, 1, x, y) \ _( 6, 56, 73, 1, x, y) \ _( 7, 64, 64, 1, x, y) \ _( 8, 80, 51, 1, x, y) \ _( 9, 96, 42, 1, x, y) \ _(10, 112, 36, 1, x, y) \ _(11, 128, 32, 1, x, y) \ _(12, 160, 25, 1, x, y) \ _(13, 192, 21, 1, x, y) \ _(14, 224, 18, 1, x, y) \ _(15, 256, 16, 1, x, y) \ _(16, 320, 64, 5, x, y) \ _(17, 384, 32, 3, x, y) \ _(18, 448, 9, 1, x, y) \ _(19, 512, 8, 1, x, y) \ _(20, 640, 32, 5, x, y) \ _(21, 768, 16, 3, x, y) \ _(22, 896, 9, 2, x, y) \ _(23, 1024, 8, 2, x, y) \ _(24, 1280, 16, 5, x, y) \ _(25, 1536, 8, 3, x, y) \ _(26, 1792, 16, 7, x, y) \ _(27, 2048, 8, 4, x, y) \ _(28, 2560, 8, 5, x, y) \ _(29, 3072, 4, 3, x, y) #endif /* ZEND_ALLOC_SIZES_H */
size = size - 1;
这个是边界情况,跟前面一样,后面出现的size暂且都认为已近减一了假设不看这个源码,我们要实现在
ZEND_MM_BINS_INFO
中找到对应的bin_num由
ZEND_MM_BINS_INFO
得知后续的增加4个为一组,分别为
2^4, 2^5, 2^6...
有了这个分组信息的话,我们要找siez对应的bin_num
找到这个size属于哪一组
并且size在组内的偏移是多少
计算组的起始位置
那现在问题转换成了上面3个小问题,我们一个一个来解决
找到size属于哪一组
最简单的办法就是比大小是吧,可以使用if...else 来一个一个比,但是显然php源码不是这样干的,那我们还有什么其它的办法呢?
我们看十进制看不出来什么名堂,就把这些值转成二进制看看吧
64 | 100 0000 80 | 101 0000 96 | 110 0000 112 | 111 0000 128 | 1000 0000 160 | 1010 0000 192 | 1100 0000 224 | 1110 0000 256 | 1 0000 0000 320 | 1 0100 0000 384 | 1 1000 0000 448 | 1 1100 0000 .....
我们看下上面的二进制,会发现每组的内的二进制长度相等,并且后面每个都比前面多一位
那就是说我们可以计算二进制的长度来决定它的分组,那么二进制的长度又是啥呢,其实就是当前二进制的最高位为
1
的位数那么问题又转换成了求二进制中最高位的
1
的位数下面给出php源码的解法,这里暂时不对其解析,只要知道它返回的是二进制中最高位的
1
的位数
int n = 16; if (size <= 0x00ff) {n -= 8; size = size << 8;} if (size <= 0x0fff) {n -= 4; size = size << 4;} if (size <= 0x3fff) {n -= 2; size = size << 2;} if (size <= 0x7fff) {n -= 1;} return n;
假设我们申请的size为65,那么这里的n返回7
计算size在组内的偏移量
这个简单,直接用size减去每组的起始siez大小然后除以当前组内的差值(16、32、64...)即可,也就是
(size-64)/16 (size-128)/32 (size-256)/64
现在来看看上一步中的返回的值,每个组分别是
7、8、9...
,那么我们现在来看看这样的数据怎么计算组内的偏移量
(size - 2^4 * 4) / 16 = size / 2^4 - 4 (size - 2^5 * 4) / 32 = size / 2^5 - 4 (size - 2^6 * 4) / 64 = szie / 2^6 - 4
那是不是可以用
7、8、9
减去3
得到4、5、6
,这样我们就可以根据它在哪一组的信息得到当前组的差值(16、32、64...)当size为65时,偏移量是不是就是
(64-64) / 2^4 = 0
计算组的起始位置
现在我们有了偏移量的信息,假定我们分组是1、2、3
那是不是就是用最高位的
1
的位数减去6
就可以得到分组信息了得到分组信息之后,怎么知道每组的起始位置呢
我们知道起始位置分别是
8、12、16...
它也是一个等差数列,就是4n+4
我们在看看size=65的那个例子
计算的偏移量是0
计算的起始位置是
4*1 + 4 = 8
所以当size=65的bin_num就是起始位置加上偏移量
8 + 0 = 8
我们再看一个size=129的例子
二进制中最高位的
1
的位数为8然后用8减去3得到5
(129 - 1 - 32 * 4) / 64 = 0
偏移量是
计算起始位置是
4 * 2 + 4 = 12
两者相加就是
12 + 0 = 0
size=193
二进制中最高位的
1
的位数为8(193 - 1 - 32 * 4) / 64 = 2
偏移量是
计算起始位置是
4 * 2 + 4 = 12
两者相加就是
12 + 2 = 14
size=1793
二进制中最高位的
1
的位数为11(1793 - 1 - 256 * 4) / 256 = 3
偏移量是
计算起始位置是
4 * 5 + 4 = 24
两者相加就是
24 + 3 = 27
代码分析
php实现代码
1 t1 = size - 1; 2 t2 = zend_mm_small_size_to_bit(t1) - 3; 3 t1 = t1 >> t2; 4 t2 = t2 - 3; 5 t2 = t2 << 2; 6 return (int)(t1 + t2);
第一行
t1 = size - 1;
是为了考虑size为64、128...这些边界情况
第二行
t2 = zend_mm_small_size_to_bit(t1) - 3;
这里调用了
zend_mm_small_size_to_bit
这个函数,我们看看这个函数
/* higher set bit number (0->N/A, 1->1, 2->2, 4->3, 8->4, 127->7, 128->8 etc) */ int n = 16; if (size <= 0x00ff) {n -= 8; size = size << 8;} if (size <= 0x0fff) {n -= 4; size = size << 4;} if (size <= 0x3fff) {n -= 2; size = size << 2;} if (size <= 0x7fff) {n -= 1;} return n;
看注释我们就知道这个函数是用来返回当前size二进制中最高位1的位数,具体的做法呢其实就是二分法
我们通过
zend_mm_small_size_to_bit
这个函数获取了size二进制中最高位1的位数,那么这个-3
是什么神奇的操作呢(size - 2^4 * 4) / 16 = size / 2^4 - 4 (size - 2^5 * 4) / 32 = size / 2^5 - 4 (size - 2^6 * 4) / 64 = szie / 2^6 - 4
这里获取二进制的位数是7、8、9...通过
-3
的操作来获取相应的 4、5、6...上问的分析中提到,我们计算size在组内的偏移量的公式
第三行
t1 = t1 >> t2;</pre> <li><p>把t1右移t2位,这又是什么神奇的操作?</p></li> <li><p>这里我们把最后计算bin_num的数学公式给写出来,它是等于每组的起始位置加上组内的偏移量</p></li> <pre class="brush:php;toolbar:false">binnum = (4n + 4) + (size / 2^n - 4) binnum = 4n + size / 2^n</pre> <ul class=" list-paddingleft-2"><li><p>所以第三行的意思我们就知道了,就是size右移2^n次方为</p></li></ul> <h4 id="第四行">第四行</h4> <ul class=" list-paddingleft-2"> <li><p><code>t2 = t2 - 3;
这个好理解,可以参照上文得到每组的起始位置的方法
第五行
t2 = t2 << 2;
我们再看看bin_num的计算公式
binnum = (4n + 4) + (size / 2^n - 4) binnum = 4n + size / 2^n
那么这行就好理解了,就是计算每组的起始位置
4n
对吧,左移两位就是乘以4
第六行
return (int)(t1 + t2);
这行没啥说的,就是返回了一个int类型的bin_num
Atas ialah kandungan terperinci php中small内存规格的计算(代码示例). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Beban mengimbangi mempengaruhi pengurusan sesi, tetapi dapat diselesaikan dengan replikasi sesi, ketegangan sesi, dan penyimpanan sesi berpusat. 1. Sesi Replikasi Salinan Data Sesi Antara Pelayan. 2. Sesi Stickiness mengarahkan permintaan pengguna ke pelayan yang sama. 3. Penyimpanan Sesi Pusat menggunakan pelayan bebas seperti Redis untuk menyimpan data sesi untuk memastikan perkongsian data.

Sessionlockingisatechniqueusedtoensureauserererersessionremainsexclusivetooneuseratatime.IScrucialFreventingDataCorruptionSandsecuritybreachesinmulti-userapplications.SessionLockingISimplementedusingserverververveChan

Alternatif untuk sesi PHP termasuk kuki, pengesahan berasaskan token, sesi berasaskan pangkalan data, dan redis/memcached. 1.Cookies Menguruskan sesi dengan menyimpan data pada klien, yang mudah tetapi rendah dalam keselamatan. 2. Pengesahan berasaskan token menggunakan token untuk mengesahkan pengguna, yang sangat selamat tetapi memerlukan logik tambahan. 3.Database-berasaskan data menyimpan data dalam pangkalan data, yang mempunyai skalabilitas yang baik tetapi boleh menjejaskan prestasi. 4. Redis/Memcached menggunakan cache yang diedarkan untuk meningkatkan prestasi dan skalabiliti, tetapi memerlukan pemadanan tambahan

SessionHijacking merujuk kepada penyerang yang menyamar sebagai pengguna dengan mendapatkan sessionId pengguna. Kaedah pencegahan termasuk: 1) menyulitkan komunikasi menggunakan HTTPS; 2) mengesahkan sumber sessionId; 3) menggunakan algoritma generasi sesi yang selamat; 4) Secara kerap mengemas kini sessionId.

Artikel ini membincangkan PHP, memperincikan bentuk penuhnya, kegunaan utama dalam pembangunan web, perbandingan dengan Python dan Java, dan kemudahan pembelajarannya untuk pemula.

PHP mengendalikan data borang menggunakan $ \ _ post dan $ \ _ mendapatkan superglobals, dengan keselamatan memastikan melalui pengesahan, sanitisasi, dan interaksi pangkalan data yang selamat.

Artikel ini membandingkan PHP dan ASP.NET, memberi tumpuan kepada kesesuaian mereka untuk aplikasi web berskala besar, perbezaan prestasi, dan ciri keselamatan. Kedua-duanya berdaya maju untuk projek besar, tetapi PHP adalah sumber terbuka dan bebas platform, sementara ASP.NET,

Kepekaan kes PHP berbeza -beza: Fungsi tidak sensitif, manakala pembolehubah dan kelas sensitif. Amalan terbaik termasuk penamaan yang konsisten dan menggunakan fungsi kes-insensitif untuk perbandingan.


Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

EditPlus versi Cina retak
Saiz kecil, penyerlahan sintaks, tidak menyokong fungsi gesaan kod

VSCode Windows 64-bit Muat Turun
Editor IDE percuma dan berkuasa yang dilancarkan oleh Microsoft

SecLists
SecLists ialah rakan penguji keselamatan muktamad. Ia ialah koleksi pelbagai jenis senarai yang kerap digunakan semasa penilaian keselamatan, semuanya di satu tempat. SecLists membantu menjadikan ujian keselamatan lebih cekap dan produktif dengan menyediakan semua senarai yang mungkin diperlukan oleh penguji keselamatan dengan mudah. Jenis senarai termasuk nama pengguna, kata laluan, URL, muatan kabur, corak data sensitif, cangkerang web dan banyak lagi. Penguji hanya boleh menarik repositori ini ke mesin ujian baharu dan dia akan mempunyai akses kepada setiap jenis senarai yang dia perlukan.

ZendStudio 13.5.1 Mac
Persekitaran pembangunan bersepadu PHP yang berkuasa
