php教程 php手册 从几个简单的程序看PHP的垃圾回收机制

从几个简单的程序看PHP的垃圾回收机制

Jun 13, 2016 am 09:39 AM
php 쓰레기 수거

每一种计算机语言都有自己的自动垃圾回收机制,让程序员不必过分关心程序内存分配,php也不例外,但是在面向对象编程(OOP)编程中,有些对象需要显式的销毁,防止程序执行内存溢出。

一、PHP 垃圾回收机制(Garbage Collector 简称GC)

在PHP中,没有任何变量指向这个对象时,这个对象就成为垃圾。PHP会将其在内存中销毁;这是PHP的GC垃圾处理机制,防止内存溢出。当一个PHP线程结束时,当前占用的所有内存空间都会被销毁,当前程序中所有对象同时被销毁。GC进程一般都跟着每起一个SESSION而开始运行的。gc目的是为了在session文件过期以后自动销毁删除这些文件。

二、__destruct /unset

__destruct() 析构函数,是在垃圾对象被回收时执行。unset 销毁的是指向对象的变量,而不是这个对象。

三、 Session 与 GC

由于PHP的工作机制,它并没有一个daemon线程来定期的扫描Session信息并判断其是否失效,当一个有效的请求发生时,PHP 会根据全局变量 session.gc_probability和session.gc_divisor的值,来决定是否启用一个GC, 在默认情况下,session.gc_probability=1, session.gc_divisor =100也就是说有1%的可能性启动GC(也就是说100个请求中只有一个gc会伴随100个中的某个请求而启动)。

GC的工作就是扫描所有的Session信息,用当前时间减去session最后修改的时间,同session.gc_maxlifetime参数进行比较,如果生存时间超过gc_maxlifetime(默认24分钟),就将该session删除。但是,如果你Web服务器有多个站点,多个站点时,GC处理session可能会出现意想不到的结果,原因就是:GC在工作时,并不会区分不同站点的session。

那么这个时候怎么解决呢?

  1. 修改session.save_path,或使用session_save_path()让每个站点的session保存到一个专用目录。
  2. 提供GC的启动率,自然,GC的启动率提高,系统的性能也会相应减低,不推荐。
  3. 在代码中判断当前session的生存时间,利用session_destroy()删除。

看下面的例子:

Example 1: gc.php

<?php 
error_reporting(E_ALL); 
$a = 'I am test.'; 
$b = & $a; 
echo $b ."n"; 
?>
로그인 후 복사

不用说 % php -f gc.php 输出结果非常明了:

hy0kl% php -f gc.php 
I am test.
로그인 후 복사

好,下一个:

<?php 
error_reporting(E_ALL); 
$a = 'I am test.'; 
$b = & $a; 
$b = 'I will change?';                                                          
echo $a ."n"; 
echo $b ."n"; 
?>
로그인 후 복사

执行结果依然很明显:

hy0kl% php -f gc.php 
I will change?
I will change?
로그인 후 복사

君请看:

<?php 
error_reporting(E_ALL); 
$a = 'I am test.'; 
$b = & $a;  
unset($a); 
echo $a ."n"; 
echo $b ."n";
?>
로그인 후 복사

是不是得想一下下呢?

hy0kl% php -f gc.php 
Notice: Undefined variable: a in /usr/local/www/apache22/data/test/gc.php on line 8
I am test.
로그인 후 복사

君再看:

<?php 
error_reporting(E_ALL); 
$a = 'I am test.'; 
$b = & $a; 
unset($b);                                                                      
echo $a ."n"; 
echo $b ."n";
?>
로그인 후 복사

其实如果 Example 3 理解了,这个与之异曲同工。

hy0kl% php -f gc.php 
I am test.
Notice: Undefined variable: b in /usr/local/www/apache22/data/test/gc.php on line 9
로그인 후 복사

君且看:

<?php 
error_reporting(E_ALL); 
$a = 'I am test.'; 
$b = & $a; 
$a = null; 
echo '$a = '. $a ."n"; 
echo '$b = '. $b ."n"; 
?>
로그인 후 복사

猛的第一感觉是什么样的?

hy0kl% php -f gc.php 
$a = 
$b =
로그인 후 복사

没错,这就是输出结果,对 PHP GC 已有深入理解的 phper 不会觉得有什么奇怪,说实话,当我第一次运行这段代码时很意外,却让我对 PHP GC 有更深刻的理解了。那么下面与之同工的例子自然好理解了。

<?php                                                                         
error_reporting(E_ALL); 
$a = 'I am test.'; 
$b = & $a; 
$b = null; 
echo '$a = '. $a ."n"; 
echo '$b = '. $b ."n"; 
?>
로그인 후 복사

下面我们来详细分析 GC 与引用:

所有例子中,创建了一个变量,这个过程通俗一点讲:是在内存中开辟了一块空间,在里面存放了一个字符串 I am test。 。 PHP 内部有个符号表,用来记录各块内存引用计数,那么此时会将这块内存的引用计数 加 1,并且用一个名为 $a 的标签(变量)指向这块内存,方便依标签名来操作内存。

对变量 $a 进行 & 操作,我的理解是找到 $a 所指向的内存,并为 $b 建立同样的一引用指向,并将存放字符串 I am test。 的内存块在符号表中引用计数 加 1。换言之,我们的脚本执行到这一行的时候,存放字符串 I am test。 的那块内存被引用了两次。这里要强调的是, & 操作是建立了引用指向,而不是指针, PHP 没有指针的概念!同时有人提出说类似于 UNIX 的文件软链接。可以在一定程度上这么理解: 存放字符 I am test。 的那块内存是我们的一个真实的文件,而变量 $a 与 $b 是针对真实文件建立的软链接,但它们指向的是同一个真实文件。 So, 我们看到,在 Example 2 中给 $b 赋值的同时, $a 的值也跟着变化了。与通过某一软链操作了文件类似。

在 Example 3 与 4 中,进行了 unset() 操作。根据实际的执行结果,可以看出: unset() 只是断开这个变量对它原先指向的内存的引用,使变量本身成为没有定义过空引用,所在调用时发出了 Notice ,并且使那块内存在符号表中引用计数 减 1,并没有影响到其他指向这块内存的变量。换言之,只有当一块内存在符号表中的引用计数为 0 时, PHP 引擎才会将这块内存回收。

看看下面的代码与其结果:

<?php 
error_reporting(E_ALL); 
$a = 'I am test.'; 
$b = & $a; 
unset($a); 
unset($a); 
unset($a); 
echo '$a = '. $a ."n"; 
echo '$b = '. $b ."n"; 
?>
로그인 후 복사

输出:

hy0kl% php -f gc.php 
Notice: Undefined variable: a in /usr/local/www/apache22/data/test/gc.php on line 10
$a = 
$b = I am test.
로그인 후 복사

第一次 unset() 的操作已经断开了指向,所以后继的操作不会对符号表的任何内存的引用记数造成影响了。

赋值 null操作是相当猛的,它会直接将变量所指向的内存在符号号中的引用计数置 0,那这块内存自然被引擎回收了,至于何时被再次利用不得而知,有可能马上被用作存储别的信息,也许再也没有使用过。但是无论如何,原来所有指向那块内存变量都将无法再操作被回收的内存了,任何试图调用它的变量都将返回 null。

<?php 
error_reporting(E_ALL); 
$a = 'I am test.'; 
$b = & $a; 
$b = null; 
echo '$a = '. $a ."n"; 
echo '$b = '. $b ."n"; 
if (null === $a) 
{                                                                               
echo '$a is null.';    
} else 
{ 
echo 'The type of $a is unknown.';    
} 
?>
로그인 후 복사

输出:

hy0kl% php -f gc.php 
$a = 
$b = 
$a is null.
로그인 후 복사

综上所述,充分说明了为什么我们在看开源产品源码的时候,常看到一些比较大的临时变量,或使用完不再调用的重用信息都会被集中或显示的赋值为 null 了。它相当于 UNIX 中直接将真实文件干掉了,所有指向它的软链接自然成了空链了。

之前在讨论到这些细节点时有很多想当然的念头,在实际的执行了测试代码后才发现: 哦,原来如此!纸上得来终觉浅,绝知此事须躬行。

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

CakePHP 프로젝트 구성 CakePHP 프로젝트 구성 Sep 10, 2024 pm 05:25 PM

이번 장에서는 CakePHP의 환경 변수, 일반 구성, 데이터베이스 구성, 이메일 구성에 대해 알아봅니다.

Ubuntu 및 Debian용 PHP 8.4 설치 및 업그레이드 가이드 Ubuntu 및 Debian용 PHP 8.4 설치 및 업그레이드 가이드 Dec 24, 2024 pm 04:42 PM

PHP 8.4는 상당한 양의 기능 중단 및 제거를 통해 몇 가지 새로운 기능, 보안 개선 및 성능 개선을 제공합니다. 이 가이드에서는 Ubuntu, Debian 또는 해당 파생 제품에서 PHP 8.4를 설치하거나 PHP 8.4로 업그레이드하는 방법을 설명합니다.

CakePHP 날짜 및 시간 CakePHP 날짜 및 시간 Sep 10, 2024 pm 05:27 PM

cakephp4에서 날짜와 시간을 다루기 위해 사용 가능한 FrozenTime 클래스를 활용하겠습니다.

CakePHP 파일 업로드 CakePHP 파일 업로드 Sep 10, 2024 pm 05:27 PM

파일 업로드 작업을 위해 양식 도우미를 사용할 것입니다. 다음은 파일 업로드의 예입니다.

CakePHP 라우팅 CakePHP 라우팅 Sep 10, 2024 pm 05:25 PM

이번 장에서는 라우팅과 관련된 다음과 같은 주제를 학습하겠습니다.

CakePHP 토론 CakePHP 토론 Sep 10, 2024 pm 05:28 PM

CakePHP는 PHP용 오픈 소스 프레임워크입니다. 이는 애플리케이션을 훨씬 쉽게 개발, 배포 및 유지 관리할 수 있도록 하기 위한 것입니다. CakePHP는 강력하고 이해하기 쉬운 MVC와 유사한 아키텍처를 기반으로 합니다. 모델, 뷰 및 컨트롤러 gu

PHP 개발을 위해 Visual Studio Code(VS Code)를 설정하는 방법 PHP 개발을 위해 Visual Studio Code(VS Code)를 설정하는 방법 Dec 20, 2024 am 11:31 AM

VS Code라고도 알려진 Visual Studio Code는 모든 주요 운영 체제에서 사용할 수 있는 무료 소스 코드 편집기 또는 통합 개발 환경(IDE)입니다. 다양한 프로그래밍 언어에 대한 대규모 확장 모음을 통해 VS Code는

CakePHP 유효성 검사기 만들기 CakePHP 유효성 검사기 만들기 Sep 10, 2024 pm 05:26 PM

컨트롤러에 다음 두 줄을 추가하면 유효성 검사기를 만들 수 있습니다.

See all articles