PHP什么时候释放内存???5


0

PHP什么时候释放内存???5

经测试,unset,和=null都不能够达到释放内存的效果。即不是立即释放。 

请问在将变量unset或=null之后,变量之前引用的内存空间什么时候释放?还是说只能等待系统回收?

问题补充:
xieye 写道
程序执行完应该回收吧

那就是程序执行完成之前内存空间一直被占用???我unset,=null之后发现进城的内存空间没有释放。
PHP 
2011年3月24日 14:42
liuzhiqiangruc liuzhiqiangruc 
21 
0  0  0
  • ta_url="/problems/61855/comments" data_action_type="dropdown" data_action_sub_type="comment" style="color: rgb(0, 102, 153);" data_comments_count="0" rel="nofollow" data_parent_id="problem_61855" >Comment添加评论
  • PHP什么时候释放内存???5 - ☆奋力拼搏☆ - 北方的…郎关注(0)

6个答案按时间排序按投票排序

0 0

有的情况下PHP所执行的查询或其他操作会占用很大的内存,如多次进行查询操作并且返回很大的数据集,这时就需使用mysql_free_result()函数手动释放内存。函数定义为: 

int mysql_free_result( int result)。 
该函数的使用很简单,不再详述。

2011年3月29日 19:25
deepfuture deepfuture 
321 
0  0  0
  • ta_url="/solutions/132614/comments" data_action_type="dropdown" data_action_sub_type="comment" style="color: rgb(0, 102, 153);" data_comments_count="0" rel="nofollow" data_parent_id="solution_132614" >Comment添加评论
0 0


PHP 无法手动释放内存,你 unset 了,也要等 GC 来自动回收,这个不是 C语言, 内存是 PHP 来管理的。 
这个只能是加大内存,或者改用其他内存占用小的算法

2011年3月29日 19:24
deepfuture deepfuture 
321 
0  0  0
  • ta_url="/solutions/132613/comments" data_action_type="dropdown" data_action_sub_type="comment" style="color: rgb(0, 102, 153);" data_comments_count="0" rel="nofollow" data_parent_id="solution_132613" >Comment添加评论
0 0

摘要 内存管理对于长期运行的程序,例如服务器守护程序,是相当重要的影响;因此,理解PHP是如何分配与释放内存的对于创建这类程序极为重要。本文将重点探讨PHP的内存管理问题。 

  一、 内存 

  在PHP中,填充一个字符串变量相当简单,这只需要一个语句"<?php $str = 'hello world '; ?>"即可,并且该字符串能够被自由地修改、拷贝和移动。而在C语言中,尽管你能够编写例如"char *str = "hello world ";"这样的一个简单的静态字符串;但是,却不能修改该字符串,因为它生存于程序空间内。为了创建一个可操纵的字符串,你必须分配一个内存块,并且通过一个函数(例如strdup())来复制其内容。 


 char *str; 
 str = strdup("hello world"); 
 if (!str) { 
  fprintf(stderr, "Unable to allocate memory!"); 
 } 


  由于后面我们将分析的各种原因,传统型内存管理函数(例如malloc(),free(),strdup(),realloc(),calloc(),等等)几乎都不能直接为PHP源代码所使用。 

  二、 释放内存 

  在几乎所有的平台上,内存管理都是通过一种请求和释放模式实现的。首先,一个应用程序请求它下面的层(通常指"操作系统"):"我想使用一些内存空间"。如果存在可用的空间,操作系统就会把它提供给该程序并且打上一个标记以便不会再把这部分内存分配给其它程序。 
当应用程序使用完这部分内存,它应该被返回到OS;这样以来,它就能够被继续分配给其它程序。如果该程序不返回这部分内存,那么OS无法知道是否这块内存不再使用并进而再分配给另一个进程。如果一个内存块没有释放,并且所有者应用程序丢失了它,那么,我们就说此应用程序"存在漏洞",因为这部分内存无法再为其它程序可用。 

  在一个典型的客户端应用程序中,较小的不太经常的内存泄漏有时能够为OS所"容忍",因为在这个进程稍后结束时该泄漏内存会被隐式返回到OS。这并没有什么,因为OS知道它把该内存分配给了哪个程序,并且它能够确信当该程序终止时不再需要该内存。 

  而对于长时间运行的服务器守护程序,包括象Apache这样的web服务器和扩展php模块来说,进程往往被设计为相当长时间一直运行。因为OS不能清理内存使用,所以,任何程序的泄漏-无论是多么小-都将导致重复操作并最终耗尽所有的系统资源。 

  现在,我们不妨考虑用户空间内的stristr()函数;为了使用大小写不敏感的搜索来查找一个字符串,它实际上创建了两个串的各自的一个小型副本,然后执行一个更传统型的大小写敏感的搜索来查找相对的偏移量。然而,在定位该字符串的偏移量之后,它不再使用这些小写版本的字符串。如果它不释放这些副本,那么,每一个使用stristr()的脚本在每次调用它时都将泄漏一些内存。最后,web服务器进程将拥有所有的系统内存,但却不能够使用它。 

  你可以理直气壮地说,理想的解决方案就是编写良好、干净的、一致的代码。这当然不错;但是,在一个象PHP解释器这样的环境中,这种观点仅对了一半。 

  三、 错误处理 

  为了实现"跳出"对用户空间脚本及其依赖的扩展函数的一个活动请求,需要使用一种方法来完全"跳出"一个活动请求。这是在Zend引擎内实现的:在一个请求的开始设置一个"跳出"地址,然后在任何die()或exit()调用或在遇到任何关键错误(E_ERROR)时执行一个longjmp()以跳转到该"跳出"地址。 

  尽管这个"跳出"进程能够简化程序执行的流程,但是,在绝大多数情况下,这会意味着将会跳过资源清除代码部分(例如free()调用)并最终导致出现内存漏洞。现在,让我们来考虑下面这个简化版本的处理函数调用的引擎代码: 

void call_function(const char *fname, int fname_len TSRMLS_DC){ 
 zend_function *fe; 
 char *lcase_fname; 
 /* PHP函数名是大小写不敏感的, 
 *为了简化在函数表中对它们的定位, 
 *所有函数名都隐含地翻译为小写的 
 */ 
 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) == FAILURE) { 
  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()这一行时,内部错误处理器就会明白该错误级别是critical,并相应地调用longjmp()来中断当前程序流程并离开call_function()函数,甚至根本不会执行到efree(lcase_fname)这一行。你可能想把efree()代码行移动到zend_error()代码行的上面;但是,调用这个call_function()例程的代码行会怎么样呢?fname本身很可能就是一个分配的字符串,并且,在它被错误消息处理使用完之前,你根本不能释放它。 

  注意,这个php_error_docref()函数是trigger_error()函数的一个内部等价实现。它的第一个参数是一个将被添加到docref的可选的文档引用。第三个参数可以是任何我们熟悉的E_*家族常量,用于指示错误的严重程度。第四个参数(最后一个)遵循printf()风格的格式化和变量参数列表式样。

2011年3月29日 19:24
deepfuture deepfuture 
321 
0  0  0
  • ta_url="/solutions/132612/comments" data_action_type="dropdown" data_action_sub_type="comment" style="color: rgb(0, 102, 153);" data_comments_count="0" rel="nofollow" data_parent_id="solution_132612" >Comment添加评论
0 0

程序执行完了之后,整个进程都没了,自然会释放。 

无论是命令行的php,还是网页执行的php

2011年3月25日 14:49
xieye xieye 
638 
0  0  4
  • ta_url="/solutions/132247/comments" data_action_type="dropdown" data_action_sub_type="comment" style="color: rgb(0, 102, 153);" data_comments_count="0" rel="nofollow" data_parent_id="solution_132247" >Comment添加评论
0 0

程序执行完了释放 
unset释放 
析构函数释放 
函数结束后局部变量释放

你可能感兴趣的:(php应用)