创意由来
之前有段时间老听java们代码走查的时候谈到gc,平常我们应该怎样一下代码更好,这样gc就可以更快的回收,哎呀,我去!我脑袋里面好像真没出现过这些呢,我为什么考虑不到这些呢,哈哈还是见识太少了,后面先后去了解了下php是内存方面的知识点,补充了下这方面的空白,后面反思了下自己为嘛会空白,1.我基本上用的php-fpm在web端的场景,它不是常驻内存,一个请求周期过后就啥都给释放了。2.在php.ini里面有设置每一个php-fpm在处理请求的过程中运行使用的最大内存(超过则被抛异常),已经给你画好圈圈了,只能这么大小玩,一般出不了大事(哎呀,这完全被保护得严严实实啊,同时也限制的严严实实,你接触不到更大的世界,故你连做大事的机会都没有,除非你意识到了什么。。。)
参考文献
PHP新垃圾回收机制之Zend GC详解
php之各种数据类型在内存中的存在角色分析(栈内存,堆内存,代码段)
<?php
$tmp = '';
echo '开始内存:'.memory_get_usage() ."\n";
//拼接一个大字符串,因为php在为变量申请内存
的时候,
//是一次性申请一定量的内存空间,才管你用不用得了这么多,那么所以这个被用来测试的字符串长度太短(暂用内存空间太小),那么unset起来就没感觉了
//有兴趣了解php变量在申请内存时候的小九九请参考上面的文献
for ($i=1;$i<10000;$i++){
$tmp .="sdgfhf";
}
echo '运行后内存:'.memory_get_usage()."\n";
unset($tmp); //或者 $tmp = null;
echo '回到正常内存:'.memory_get_usage()."\n";
//输出一下结果:
//开始内存:354672
//运行后内存:416144
//回到正常内存:354704
//对象数据类型也一样可以释放
class docotr {
public $t = "fgfdgdfgdfhgjkljslfjlksdfsjlkfjlksjdkfjlkslkflkjljfljoafnewehtuiodjnjlkasjlkdjkaskldjlkajslkdlkaskldklsajlkdlksalkdklsadklasjdjaklsjdlkasjdlkajlkdjkljlkgklfdjlgnjngjfjgds";
public function str() {
echo "我是一个字符串!\n";
}
}
echo '开始内存:'.memory_get_usage() ."\n";
$a = new docotr(); //new 第一个对象的时候下面显示内存在占用在升高(温馨提示用于测试的对象得占点内存才行,不然无感知)
echo '运行后内存1:'.memory_get_usage()."\n";
$a = new docotr(); //再$a继续new对象,你就会发现内存没有升高了因为$a指向了新对象,之前的那个对象就被gc回收掉了
echo '运行后内存2:'.memory_get_usage()."\n";
unset($a); //直接调用unset()来销毁
echo '回到正常内存:'.memory_get_usage()."\n";
从上面的demo中我们可以很轻易的看出php提前释放内存运作,在这里强调下误区(我自己的经历出发),我之前以为只要将一个变量的引用计数变为0就会被释放掉,其实不然 是有自己的一套规律的,由于文献中已经阐述得够清楚了在此就不重复了
代码规范总结:
1.尽量不要在一个函数里面code太长,太长会导致你函数里面的变量占用内存时间过长,也不会不够直观,对维护也不够友好...
2.程序中如果有变量占用内存很大,然后后面又会执行一个跟此变量没关系但耗时又耗内存的逻辑代码块,此时我们可以考虑提前释放掉它(一般是不需要我们操这心的)
3.未完待续吧,后面再整一个专门针对代码设计的(模块化设计,通讯设计等)...
php内存管理总结:
1.php是可以提前释放内存的(也是有gc这么个角色的)
2.php内存释放是有自己的一套规律的,我们应该去了解它的规律这样以后就能写出更友好内存管理的code了(去文献里面看规律)
网友评论