去炮台湾转了圈

  传说在宝山有一个炮台湾湿地公园,前两天在报上又看到说那儿有海鸥,于是昨天就去了一趟。三号线坐到水产路,那就已经是感觉很遥远了,然后再坐几站公交车才到。那宝山11路我真怀疑是不是总共只有一辆车。

  那个公园门票倒只要5块,不过公园也不算大。在江边上也没看到多少湿地,那海鸥么,好不容易才远远地看到了几只。不过我的相机能力有限,我的水平也有限,没拍到像样的。 倒是很神奇地在成群的大货轮前,还有一只小渔船。

 P.S. 又做了一个模板。之前的那个老横说很卡,但我一直没觉得。但有一次我在拷文件的时候,终于发现在CPU忙的情况下,IE上确实很卡,不过其他浏览器还是没问题。看来IE在渲染复杂页面的效率还是不高。现在的这个模板要简单的多,不会再有问题了。照片是在玉柱山拓展的时候拍的黎明时的群山。

 

php扩展开发学习笔记 7

引用计数

  php采用的内存管理和垃圾回收方法是基于引用计数的。之前说过,在zval结构里有一个refcount是表示引用计数,还有一个is_ref表示是否是个引用变量。那么php代码的实际运行中,又是如何处理的呢?

  比如这样的php代码:
$a = “hello”;
$b = $a;
这时候并不像很多人认为的那样,在内存里把”hello”这个字符串复制了一份,而只是把$b指向了和$a对应的同一个zval,然后把那个zval的refcount + 1。这样避免了一次内存拷贝。但如果在这之后改变了其中一个变量的值,比如$b.= ” world”;又会如何呢?这时候才会分配一个新的zval给$b,然后把原先那个zval的refcount – 1。这就是传说中的copy on write。就是说,在改变值得时候才会有内存拷贝。

  那么引用变量又会如何呢? 比如
$a = “hello”;
$b = &$a;
和前面一样,$a, $b还是指向同一个zval。只是还要把这个zval的is_ref置为1。之后再改变$a或者$b的时候就不会再发生拷贝。那么
$a = “hello”;
$b = &$a;
$c = $a;
这时又会如何呢?因为$c并不是一个引用变量,因此不能和$a, $b共用一个zval。因此在$c = $a的时候会直接产生一个新的zval。

  因此,在php中,使用引用对改善性能并不会有多少作用,通常情况下还会使情况更糟。所以,引用还是只在真正需要的时候才用为好。

  再说说垃圾回收。每个zval都有一个refcount表示它的变量的引用数。不管对于普通变量还是引用变量都是如此。refcount的初始值一般为1。每当增加一个引用时就+1,减少一个引用,比如unset时就会-1。当refcount为0的时候,php就会把它释放掉。这就是基于引用计数的垃圾回收方法。

使用zval

初始化zval
MAKE_STD_ZVAL(zval*);
这个宏的左右是创建一个zval,完成初始化(如将ref_count置为1,isref置为false)并把指针赋给参数。

赋值
写扩展的时候不可避免的要用到把一个zval复制到另一个zval,就是类似$a = $b;的操作。对于简单的值或许手动维护引用计数之类的还不算很麻烦但对于数组,对象之类的就需要一层层递归进去,因此就有了一个zval_copy_ctor来做着件事情。
原有一个zval* p_zval_b,
zval* p_zval_a;
MAKE_STD_ZVAL(p_zval_a); //初始化p_zval_a
*p_zval_a = *p_zval_b;
zval_copy_ctor(p_zval_a);
这里,zval_copy_ctor完成了类似赋值的操作,包括引用计数处理,对于hash值的成员处理等。

 释放一个zval则是使用zval_ptr_dtor(**zval)。注意它的参数。它会释放掉为这个zval所分配的内存。

 

php扩展开发学习笔记 6

内存管理

  在C语言里,分配内存有一组alloc函数,比如malloc、calloc、realloc。php为了更方便,更安全地管理内存,自己提供了一组内存分配的函数:emalloc、ecalloc、erealloc,此外还有estrdup用于拷贝内存,efree用于释放由前面那些函数分配的内存。他们的用法和标准C函数的一样。这组e开头的函数分配的内存空间只存在于一次请求。在请求结束后,php会自动释放掉。这就减少了由于没有释放掉内存而造成的内存泄露的可能。

  如果需要分配的内存在整个进程运行时都保持,而不是在请求处理结束后自动释放,则还有一组pe开头的函数,如pemalloc、pecalloc等。这组函数比标准C函数的多一个参数,即分配的内存是否持久,当这个参数为1时,即表示分配的是持久的内存,不会随着请求结束而自动释放。如:pemalloc(sizeof(long) * 100, 1);。

  此外,为了方便使用,还提供了safe_emalloc和safe_pemalloc这两个函数。 safe_emalloc的原型如下:void *safe_emalloc(size_t size, size_t count, size_t addtl);。参数分别表示单元的大小,单元的个数,以及偏移。实际分配的空间大小就是size * count + addtl。safe_pemalloc与之类似。这两个函数还有一个作用就是避免手工做上面的计算时,可能造成整数溢出,而导致分配的内存大小小于预期或者是个负数。

 

今年的春晚

  其实我大年三十没看春晚,但是今天还是看了半场的重播。虽说还是一贯的粉饰太平,不过仔细看,还是会发觉一些有趣之处的。

  开场有一个歌舞,一群小孩子给当作木偶或者说傀儡牵着线耍。我就琢磨着,这算不算是讽刺现在的教育呢?难道春晚也玩冷幽默么?

  又看到爬杆,想起了以前的一个叫做波斯王子的游戏。话说当时我们都管他叫波斯猴子。看样子王子还是比不过专业的杂技演员啊~

  又是一个歌舞,看着看着就奇怪,那些男的蹲在女的裙子那边做啥呢?仔细一看,原来在往上面喷红色……。难道不能用更高明的办法吗?难道没看到过耍魔术的是怎么换衣服的么?

  有个说军嫂的小品,然后我就想,大年三十都有台风,原来这个厄尔尼诺已经到这地步了。太可怕了。

  又有傻根的小品,看着看着突然发现,冯巩的工资卡原来是招行的信用卡。好高级……这算不算是营销呢?算不算是植入式广告呢?

上海的下雪天

  这些天上海下了很大的雪,尤其是昨晚到今天早上,似乎是我见过的最大的雪。据新闻说,也是建国以来最大的。上班路上,看到路边的汽车上盖的雪厚得像馒头一样。嗯,不过这个馒头只是颜色厚度像,不符合国家标准。不是圆的,也没有小麦香。或者说像奶油蛋糕?地上的雪踩上去也有了松软的感觉,算是真正的雪了。

  在这个难得下回雪,更难得能积起来的地方,以前每次下雪都是一件让人兴奋的事情。而这次大雪却不一样。当身边的同事、朋友因为这场雪而让回家过年成了一件难事,更多的人因为这场雪而遭灾的时候,就对这雪有了一种复杂的感觉。2008年的这场雪是偶然的吗?以后几年还会这样吗?今天看气象预报,南方总算是可以看到红太阳了。