load(); ?&g" name=description>

InfoQ

交流

讨论:PHP + ORACLE8i为何出现重大内存泄漏

作者 yonnie 发布于 0000-00-00 分类:数据库技术

无论在WINDOWS下还是在LINUX下, PHP在读取ORACLE的CLOB或BLOB字段时, 都会引起APACHE的内存泄漏, 而且泄漏的内存与读取的字段值实际大小和读取的记录数相关, 一直增长直至系统内存耗尽。

以下是一段测试代码,请教各路高手解燃眉之急。多谢了!
<?php

$conn = ocilogon("username","password");
$query = "SELECT clob_fldname FROM tablename";
$stmt = OCIParse ($conn, $query);
OCIExecute($stmt, OCI_DEFAULT);
ocifetchinto($stmt, $arr, OCI_ASSOC);
$result = $arr["CLOB_FLDNAME"]->load();

?>



逛论坛交流PHP + ORACLE8i为何出现重大内存泄漏

加入书签
digg+,
reddit+,
del.icio.us+,
dzone+

10 条回复

回复

你用的是ocilogn 非持久连接,根据PH.. 发表人 books 发表于 12月01日
没有用,用上这些函数释放资源仍然表现.. 发表人 yonnie 发表于 12月01日
程序如下: <?php $conn .. 发表人 yonnie 发表于 12月01日
我已查明,是读取CLOB字段时的load()函.. 发表人 yonnie 发表于 12月01日
请参考以下文章 http://icywave.myr.. 发表人 books 发表于 12月01日
用另一种方法仍然不行: <?php .. 发表人 yonnie 发表于 12月01日
去PHP版块看ROOKIE的文章,我估计他说对.. 发表人 books 发表于 12月01日
ROOKIE所说的是针对CLOB写操作时的情况.. 发表人 yonnie 发表于 12月01日
我的环境是Windows XP + PHP 4.3.3 + A.. 发表人 yonnie 发表于 12月01日
  1. 你用的是ocilogn
    非持久连接,根据PHP+MYSQL的说法是PHP页面执行完毕自动关闭连接释放资源。
    PHP+OCI也是这种说法
    但是我曾经用PHP+ORACLE非持久连接(ora_logon)发现PHP页面执行完毕并不自动释放资源(或者说没有正确释放),造成内存泄露。于是我采取在每个页面结束时主动调用ora_logoff,则没有造成内存泄露,资源被正确释放。

    你用PHP+OCI试试主动关闭连接ocilogoff看还会不会造成内存泄露(我没仔细检查过OCI方式)

  2. 最好还要主动释放其他OCI占用的资源比如ocifreecursor 释放游标
    ocifreedesc -- Deletes a large object descriptor
    ocifreestatement -- Free all resources associated with a statement
    ocifreecollection -- 该函数目前暂时没有参考文档

  3. 没有用,用上这些函数释放资源仍然表现出APACHE的虚拟内存无法释放

  4. 程序如下:

    <?php

    $conn = ociplogon("username","password","DB");
    $query = "select CLOB_FIELDNAME from TABLENAME";
    $stmt = OCIParse ($conn, $query);
    OCIExecute($stmt, OCI_DEFAULT);
    while(ocifetchinto($stmt, $arr, OCI_ASSOC)){
    $result = $arr["CLOB_FIELDNAME"]->load();
    echo $result;
    }
    if (ocifreecollection()) echo "OK1";
    if(ocifreedesc()) echo "OK2";
    if(ocifreestatement($stmt)) echo "OK3";
    if(ocilogoff($conn)) echo "OK4


    ";

    ?>

  5. 我已查明,是读取CLOB字段时的load()函数引起的,但没有解决办法

  6. 请参考以下文章
    http://icywave.myrice.com/icyschool/php/p010405b.htm
    该文章提供了两种方法操作LOB,你使用的正是文中不提倡的第一种方法。你可以参考一下文中的第二种方法

    并注意其中这样一段话:

    QUOTE:
    秘密就在PCIFetchInfo(books按:原文笔误,此处应为OCIFetchInfo)的第三个参数上:OCI_RETURN_LOBS。第三个参数是FETCH的模式,如果OCI_RETURN_LOBS,就直接把LOB的值放到结果数组中,而不是LOB定位符,也就不用LOB对象的load()方法了

    试试看行不行,希望对你有所帮助!
    呵呵,行的话请把结果也告诉我,

  7. 用另一种方法仍然不行:
    <?php

    $conn = ociplogon("username","password","sid");
    $query = "select CLOB_FIELDNAME from TABLENAME";
    $stmt = OCIParse ($conn, $query);
    OCIExecute($stmt);
    while(ocifetchinto($stmt, $arr, OCI_ASSOC+OCI_RETURN_NULLS+OCI_RETURN_LOBS)){
    echo $arr["CLOB_FIELDNAME"];
    }
    if (ocifreecollection()) echo "OK1";
    if(ocifreedesc()) echo "OK2";
    if(ocifreestatement($stmt)) echo "OK3";
    if(ocilogoff($conn)) echo "OK4


    ";

    ?>

  8. 去PHP版块看ROOKIE的文章,我估计他说对了,是ORACLE没有自动提交造成的

  9. ROOKIE所说的是针对CLOB写操作时的情况有用,但在读操作时不存在COMMIT的问题。我也试过,提交与否,反应出来的现象是一样的

  10. 我的环境是Windows XP + PHP 4.3.3 + APACHE 1.3.26,在Windows任务管理器里可以看到,一般APACHE有两个进程,一个监视进程,一个工作进程,每个进程都占用一定的内存和虚拟内存,上面那段代码每执行一次,APACHE工作进程的虚拟内存就增大若干,实际增大的值与读取的CLOB字段的内容大小和读取的记录数成正比,直至机器资源耗尽。




  11. 我有话要讲:(可以匿名发表, 发广告的有多远请滚多远!!!)

    昵称: 请输入验证码:


抢着回答

我升级了

老板叫我当技术部副经理啊,感觉压力好大哦

请问用php怎样实现传真功能

我想直接在 网上发传真,多方便,请大哥您支持一下

偶失恋了..

半年前的今天

灌水的下场

:confused: :confused: :confused: :confused: :confused: :conf...

想学php请近?

到 www.myferly.com下载PHP Server Builder 1.2 for windows安装...

有奖 问答 !!!!

哈哈哈哈哈哈 那位大侠 知道 耶稣老大 的 爸爸 叫什么名字

很菜的一个问题

-----------------checkadmin.php -------------------- $sql=...

求助,PHP,SQL查询。

table1中有type,t_id等列名.table2中有id,name等列名.其中table1...

到技术区

支 持...

本人挂机中!!!!!!

心情有点乱,挂机听听歌!!!! :crying: :crying: :crying: :cryi...

[]