zoukankan      html  css  js  c++  java
  • php内存管理

    php内存处理
    1、错误处理
    为了实现从用户端(PHP语言中)"跳出",需要使用一种方法来完全"跳出"一个活动请求。这个功能是在内核中实现的:在一个请求的开始设置一个"跳出"地址,然后在任何die()或exit()调用或在遇到任何关键错误(E_ERROR)时执行一个longjmp()以跳转到该"跳出"地址。

    void call_function(const char *fname, int fname_len TSRMLS_DC)
    {
    zend_function *fe;
    char *lcase_fname;
    /* php函数的名字是大小写不敏感的
    * 我们可以在function tables里找到他们
    * 保存的所有函数名都是小写的。
    */
    lcase_fname = estrndup(fname, fname_len);
    zend_str_tolower(lcase_fname, fname_len);

    if (zend_hash_find(EG(function_table),lcase_fname, fname_len + 1, (void **)&fe) == SUCCESS)
    {
    zend_execute(fe->op_array TSRMLS_CC);
    }
    else
    {
    php_error_docref(NULL TSRMLS_CC, E_ERROR,"Call to undefined function: %s()", fname);
    }
    efree(lcase_fname);
    }

    当php_error_docref这个函数被调用的时候,便会触发内核中的错误处理机制,根据错误级别来决定是否调用longjmp来终止当前请求并退出call_function函数,从而efree函数便永远不会被执行了。

    其实php_error_docref()函数就相当与php语言里的trigger_error()函数.它的第一个参数是一个将被添加到docref的可选的文档引用第三个参数可以是任何我们熟悉的E_*家族常量,用于指示错误的严重程度。后面的两个参数就像printf()风格的格式化和变量参数列表式样。

    2、zend内存管理器
    内存申请,隐式释放

    3、引用计数,写时复制

    引用计数
    zval *helloval;
    MAKE_STD_ZVAL(helloval);
    ZVAL_STRING(helloval, "Hello World", 1);
    zend_hash_add(EG(active_symbol_table), "a", sizeof("a"),&helloval, sizeof(zval*), NULL);
    ZVAL_ADDREF(helloval); //这句很特殊,我们显式的增加了helloval结构体的refcount
    zend_hash_add(EG(active_symbol_table), "b", sizeof("b"),&helloval, sizeof(zval*), NULL);

    写时复制
    zval *get_var_and_separate(char *varname, int varname_len TSRMLS_DC)
    {
    zval **varval, *varcopy;
    if (zend_hash_find(EG(active_symbol_table),varname, varname_len + 1, (void**)&varval) == FAILURE)
    {
    /* 如果在符号表里找不到这个变量则直接return */
    return NULL;
    }

    if ((*varval)->refcount < 2)
    {
    //如果这个变量的zval部分的refcount小于2,代表没有别的变量在用,return
    return *varval;
    }

    /* 否则,复制一份zval*的值 */
    MAKE_STD_ZVAL(varcopy);
    varcopy = *varval;

    /* 复制任何在zval*内已分配的结构*/
    zval_copy_ctor(varcopy);

    /* 从符号表中删除原来的变量
    * 这将减少该过程中varval的refcount的值
    */
    zend_hash_del(EG(active_symbol_table), varname, varname_len + 1);

    /* 初始化新的zval的refcount,并在符号表中重新添加此变量信息,并将其值与我们的新zval相关联。*/
    varcopy->refcount = 1;
    varcopy->is_ref = 0;
    zend_hash_add(EG(active_symbol_table), varname, varname_len + 1,&varcopy, sizeof(zval*), NULL);

    /* 返回新zval的地址 */
    return varcopy;
    }

  • 相关阅读:
    账户与安全
    VIM 文档编辑
    ubuntu下搭建Discuz
    数据库管理及增删改查基本操作小结
    poj 3320 jessica's Reading PJroblem 尺取法 -map和set的使用
    poj 3579 Median 二分套二分 或 二分加尺取
    poj 3685 Matrix 二分套二分 经典题型
    POJ 3061  Subsequence   尺取法   挑战146页
    poj 2976 Dropping tests 二分搜索+精度处理
    Codeforces Round #325 (Div. 2) A. Alena's Schedule 暴力枚举 字符串
  • 原文地址:https://www.cnblogs.com/tangchuanyang/p/6207158.html
Copyright © 2011-2022 走看看