我升级了
老板叫我当技术部副经理啊,感觉压力好大哦
- 娱乐乐园,
load(); ?&g" name=description>
作者 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为何出现重大内存泄漏
你用的是ocilogn
非持久连接,根据PHP+MYSQL的说法是PHP页面执行完毕自动关闭连接释放资源。
PHP+OCI也是这种说法
但是我曾经用PHP+ORACLE非持久连接(ora_logon)发现PHP页面执行完毕并不自动释放资源(或者说没有正确释放),造成内存泄露。于是我采取在每个页面结束时主动调用ora_logoff,则没有造成内存泄露,资源被正确释放。
你用PHP+OCI试试主动关闭连接ocilogoff看还会不会造成内存泄露(我没仔细检查过OCI方式)
最好还要主动释放其他OCI占用的资源比如ocifreecursor 释放游标
ocifreedesc -- Deletes a large object descriptor
ocifreestatement -- Free all resources associated with a statement
ocifreecollection -- 该函数目前暂时没有参考文档
没有用,用上这些函数释放资源仍然表现出APACHE的虚拟内存无法释放
程序如下:
<?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
";
?>
我已查明,是读取CLOB字段时的load()函数引起的,但没有解决办法
请参考以下文章
http://icywave.myrice.com/icyschool/php/p010405b.htm
该文章提供了两种方法操作LOB,你使用的正是文中不提倡的第一种方法。你可以参考一下文中的第二种方法
并注意其中这样一段话:QUOTE: 秘密就在PCIFetchInfo(books按
:原文笔误,此处应为OCIFetchInfo)的第三个参数上:OCI_RETURN_LOBS。第三个参数是FETCH的模式,如果OCI_RETURN_LOBS,就直接把LOB的值放到结果数组中,而不是LOB定位符,也就不用LOB对象的load()方法了
试试看行不行,希望对你有所帮助!
呵呵,行的话请把结果也告诉我,
用另一种方法仍然不行:
<?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
";
?>
去PHP版块看ROOKIE的文章,我估计他说对了,是ORACLE没有自动提交造成的
ROOKIE所说的是针对CLOB写操作时的情况有用,但在读操作时不存在COMMIT的问题。我也试过,提交与否,反应出来的现象是一样的
我的环境是Windows XP + PHP 4.3.3 + APACHE 1.3.26,在Windows任务管理器里可以看到,一般APACHE有两个进程,一个监视进程,一个工作进程,每个进程都占用一定的内存和虚拟内存,上面那段代码每执行一次,APACHE工作进程的虚拟内存就增大若干,实际增大的值与读取的CLOB字段的内容大小和读取的记录数成正比,直至机器资源耗尽。
10 条回复
回复