内存详解: 详解PHP内存池中的存储层

PHP的内存管理器是分层(hierarchical)的。这个管理器共有三层:存储层(storage)、堆(heap)层和 emalloc/efree 层。存储层通过 malloc()、mmap() 等函数向系统真正的申请内存,并通过free()函数释放所申请的内存。
存储层通常申请的内存块都比较大,这里申请的内存大并不是指storage层结构所需要的内存大,只是堆层通过调用存储层的分配方法时,其以段的格式申请的内存比较大,存储层的作用是将内存分配的方式对堆层透明化。
首先看storage层的结构:
/* Heaps with user defined storage */  
typedef struct _zend_mm_storage zend_mm_storage;  
   
typedef struct _zend_mm_segment {  
    size_t    size;  
    struct _zend_mm_segment *next_segment;  
} zend_mm_segment;  
   
typedef struct _zend_mm_mem_handlers {  
    const char *name;  
    zend_mm_storage* (*init)(void *params);    //初始化函数  
    void (*dtor)(zend_mm_storage *storage);    //析构函数  
    void (*compact)(zend_mm_storage *storage);  
    zend_mm_segment* (*_alloc)(zend_mm_storage *storage, size_t size);    //内存分配函数  
    zend_mm_segment* (*_realloc)(zend_mm_storage *storage, zend_mm_segment *ptr, size_t size);    //重新分配内存函数  
    void (*_free)(zend_mm_storage *storage, zend_mm_segment *ptr);    //释放内存函数  
} zend_mm_mem_handlers;  
   
struct _zend_mm_storage {  
    const zend_mm_mem_handlers *handlers;    //处理函数集  
    void *data;  
};  
内存的分配方式,调用的函数是_zend_mm_storage结构中的处理函数集,而内存是以段的形式表现的。
4种内存方案
PHP在存储层共有4种内存分配方案: malloc,win32,mmap_anon,mmap_zero。默认使用malloc分配内存,如果设置了ZEND_WIN32宏,则为windows版本,调用HeapAlloc分配内存,剩下两种内存方案为匿名内存映射,并且PHP的内存方案可以通过设置变量来修改。
官方说明如下:
The Zend MM can be tweaked using ZEND_MM_MEM_TYPE and ZEND_MM_SEG_SIZE environment variables. Default values are “malloc” and “256K”.Dependent on target system you can also use “mmap_anon”, “mmap_zero” and “win32″ storage managers.
在代码中,对于这4种内存分配方案,分别对应实现了zend_mm_mem_handlers中的各个处理函数。配合代码的简单说明如下:
/* 使用mmap内存映射函数分配内存 写入时拷贝的私有映射,并且匿名映射,映射区不与任何文件关联。*/  
# define ZEND_MM_MEM_MMAP_ANON_DSC {"mmap_anon", zend_mm_mem_dummy_init, zend_mm_mem_dummy_dtor, zend_mm_mem_dummy_compact, zend_mm_mem_mmap_anon_alloc, zend_mm_mem_mmap_realloc, zend_mm_mem_mmap_free}   本文链接http://www.cxybl.com/html/wlbc/Php/20130922/40142.html

时间: 2024-09-11 23:33:25

内存详解: 详解PHP内存池中的存储层的相关文章

共享池中保留池的调整(shared_pool_reserved_size)

--************************************************* -- 共享池中保留池的调整(shared_pool_reserved_size) --*************************************************   1.何谓保留池         简言之,保留一部分内存空间以备不时之需.通常情况下,Oracle会将大的内存请求分割成小的内存块来满足需求.而对于大的内     存且为连续的内存空间请求,如果在共享池中未找

详解Java的堆内存与栈内存的存储机制_java

堆与内存优化    今天测了一个项目的数据自动整理功能,对数据库中几万条记录及图片进行整理操作,运行接近到最后,爆出了java.lang.outOfMemoryError,java heap space方面的错误,以前写程序很少遇到这种内存上的错误,因为java有垃圾回收器机制,就一直没太关注.今天上网找了点资料,在此基础上做了个整理.  一.堆和栈     堆-用new建立,垃圾回收器负责回收          1.程序开始运行时,JVM从OS获取一些内存,部分是堆内存.堆内存通常在存储地址的

nodeJs内存泄漏问题详解_node.js

之前一次偶然机会发现,react 在server渲染时,当NODE_ENV != production时,会导致内存泄漏.具体issues: https://github.com/facebook/react/issues/7406 .随着node,react同构等技术地广泛运用,node端内存泄漏等问题应该引起我们的重视.为什么node容易出现内存泄漏以及出现之后应该如何排查,下面通过一个简单的介绍以及例子来说明. 首先,node是基于v8引擎基础上,其内存管理方式与v8一致.下面简单介绍v8

ARC内存管理机制详解

        ARC在OC里面个人感觉又是一个高大上的牛词,在前面Objective-C中的内存管理部分提到了ARC内存管理机制,ARC是Automatic Reference Counting---自动引用计数.有自动引用计数,那么就得有手动引用计数MRC(Mannul Reference Counting),前面已经提到过了MRC.那么在ARC模式下是不是意味着我们就可以一点也不用进行内存管理的呢?并不是这样的,我们还需要代码进行内存的管理.下面会结合着代码把OC中的ARC机制做一个详细的

JavaScript的内存释放问题详解_javascript技巧

本文详细的讲解了JavaScript及IE浏览器对内存的管理和释放的时机和方法,希望对前端开发人员有所帮助. 一个内存释放的实例 复制代码 代码如下: <SCRIPT LANGUAGE="JavaScript"> <!-- strTest = "1"; for ( var i = 0; i < 25; i ++ ) { strTest += strTest; } alert(strTest); delete strTest; CollectG

C语言、C++内存对齐问题详解_C 语言

这也可以? 复制代码 代码如下: #include <iostream> using namespace std;   struct Test_A {      char a;      char b;      int c; };   struct Test_B {      char a;      int c;      char b; };   struct Test_C {      int c;      char a;      char b; };   int main() {

Linux下套接字详解(七)----线程池accept处理高并发connect

前言 服务器在调用listen和accept后,就会阻塞在accept函数上,accpet函数返回后循环调用accept函数等待客户的TCP连接. 我们知道服务器段listen套接字能处理的连接数与监听队列的大小有关,如果这时候又大量的用户并发发起connec连接,那么在listen有队列上限(最大可接受TCP的连接数)的情况下,有多少个connect会成功了. 试验证明,当连接数远远高于listen的可连接数上限时,客户端的大部分TCP请求会被抛弃,只有当listen监听队列空闲或者放弃某个连

某内存池中的指针用法

内存池实现有许多种,各有不同的优缺点. 这里不是主要说内存池,只是觉得这个内存池中的指针用得很飘逸! template <class T,int AllocSize = 50>   class MemPool   {   public:       static void* operator new(size_t allocLength)       {           if(!mStartPotinter)           {               MyAlloc();    

vs2012-C# 写的form程序 调试时突然出先“尝试读取或写入受保护的内存。这通常指示其他内存已损坏。”

问题描述 C# 写的form程序 调试时突然出先"尝试读取或写入受保护的内存.这通常指示其他内存已损坏." 前几天写的一个程序,今天准备用了,当打开exe文件的时候突然停止,然后进入vs2012调试报错,在数据库链接那个块的打开数据库(看图片),不知道怎么回事.昨天是用还好着呢,还有将exe文件放到别人的电脑上就可以是用!求各路大神给个觉解方法吧!急急急啊!还有个问题,所有链接数据库的方法都抱着个错! 解决方案 C#尝试读取或写入受保护的内存.这通常指示其他内存已损坏.C#尝试读取或写