php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #50789 Memory leak fetching OCI8 LOB fields
Submitted: 2010-01-18 08:33 UTC Modified: 2010-04-26 00:33 UTC
Votes:1
Avg. Score:4.0 ± 0.0
Reproduced:0 of 1 (0.0%)
From: szymon dot latkowski at geomar dot pl Assigned: sixd (profile)
Status: No Feedback Package: OCI8 related
PHP Version: 5.3.1 OS: Windows XP
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: szymon dot latkowski at geomar dot pl
New email:
PHP Version: OS:

 

 [2010-01-18 08:33 UTC] szymon dot latkowski at geomar dot pl
Description:
------------
After fetching CLOB field in Oracle XE DB installed on the same PC as PHP and Apache 2.2.14 with OCI_RETURN_LOBS provided as param to oci_fetch_all() and oci_fetch_array() functions, oci8 extension does not properly flush memory reserved for LOB objects.

Reproduce code:
---------------
<?php

$dsn  = "VALID_DATA_SOURCE_NAME";
$user = "VALID_USER_NAME";
$pass = "VALID_PASSWORD";

echo "<pre>start\n";

oci_internal_debug(true);
$conn = oci_connect($user, $pass, $dsn);

// sample table has this schema and has more than one row(s).
//     CREATE TABLE OWN1.TEST (COLUMN1 CLOB);
// COLUMN1 must not be empty - minimum 2 rows are expected
$stmt = oci_parse($conn, "SELECT SELECT COLUMN1 FROM OWN1.TEST");
oci_execute($stmt,OCI_DEFAULT);

$res = array();
$row = '';
/*
while($row = oci_fetch_array($stmt, OCI_ASSOC+OCI_RETURN_NULLS+OCI_RETURN_LOBS)) {
	$res[] = $row;
}
*/

oci_fetch_all($stmt, $res, $SQL_LIMIT_FROM, $SQL_LIMIT_COUNT, OCI_FETCHSTATEMENT_BY_ROW+OCI_RETURN_LOBS);
oci_free_statement($stmt);
var_dump($res[0]);

oci_close($conn);

echo "stop\n</pre>";

?>

Expected result:
----------------
OCIDescriptorFree function should be called during SQL result fetching, not at the end of PHP script. In above script every single call of OCIDescriptorFree should take place before "stop" is printed out. Now only one call of OCIDescriptorFree take place before this piece of code. The expected result should be similar to that described in this article: http://blogs.oracle.com/opal/2008/01/.

Actual result:
--------------
When I have about 70000 rows in my table, PHP reserves a few MB of memory and releases it at the end of the script consuming 100% of processor and PHP does not release it completely. In our system with hundreds of thousands of client calls it results in Apache crash every hour because of lack of memory and PHP script crashes ocassionaly when it exceeds php.ini "memory_limit" value in single script (with lots of LOB objects fetch).

Result of my code from browser:

start
OCI8 DEBUG: OCINlsEnvironmentVariableGet at (ext\oci8\oci8.c:1764) 
OCI8 DEBUG L1: Got NO cached connection at (ext\oci8\oci8.c:1809) 
OCI8 DEBUG L1: using shared pool: (0x5677770) at (ext\oci8\oci8.c:2910) 
OCI8 DEBUG: OCIHandleAlloc at (ext\oci8\oci8.c:2921) 
OCI8 DEBUG: OCIHandleAlloc at (ext\oci8\oci8.c:2931) 
OCI8 DEBUG: OCIAttrGet at (ext\oci8\oci8.c:2964) 
OCI8 DEBUG: OCIAttrGet at (ext\oci8\oci8.c:2965) 
OCI8 DEBUG L1: (numopen=0)(numbusy=0) at (ext\oci8\oci8.c:2967) 
OCI8 DEBUG: OCISessionGet at (ext\oci8\oci8.c:2978) 
OCI8 DEBUG: OCIAttrGet at (ext\oci8\oci8.c:2993) 
OCI8 DEBUG: OCIAttrGet at (ext\oci8\oci8.c:2995) 
OCI8 DEBUG: OCIContextGetValue at (ext\oci8\oci8.c:2997) 
OCI8 DEBUG: OCIContextGetValue at (ext\oci8\oci8.c:3092) 
OCI8 DEBUG: OCIMemoryAlloc at (ext\oci8\oci8.c:3099) 
OCI8 DEBUG: OCIContextSetValue at (ext\oci8\oci8.c:3113) 
OCI8 DEBUG: OCIAttrSet at (ext\oci8\oci8.c:3023) 
OCI8 DEBUG L1: New Non-Persistent Connection address: (0x5c1dc40) at (ext\oci8\oci8.c:2035) 
OCI8 DEBUG L1: num_persistent=(0), num_links=(1) at (ext\oci8\oci8.c:2037) 
OCI8 DEBUG: OCIHandleAlloc at (ext\oci8\oci8_statement.c:57) 
OCI8 DEBUG: OCIStmtPrepare2 at (ext\oci8\oci8_statement.c:72) 
OCI8 DEBUG: OCIAttrSet at (ext\oci8\oci8_statement.c:122) 
OCI8 DEBUG: OCIAttrGet at (ext\oci8\oci8_statement.c:396) 
OCI8 DEBUG: OCIStmtExecute at (ext\oci8\oci8_statement.c:420) 
OCI8 DEBUG: OCIAttrGet at (ext\oci8\oci8_statement.c:449) 
OCI8 DEBUG: OCIParamGet at (ext\oci8\oci8_statement.c:469) 
OCI8 DEBUG: OCIAttrGet at (ext\oci8\oci8_statement.c:478) 
OCI8 DEBUG: OCIAttrGet at (ext\oci8\oci8_statement.c:488) 
OCI8 DEBUG: OCIAttrGet at (ext\oci8\oci8_statement.c:498) 
OCI8 DEBUG: OCIAttrGet at (ext\oci8\oci8_statement.c:508) 
OCI8 DEBUG: OCIAttrGet at (ext\oci8\oci8_statement.c:521) 
OCI8 DEBUG: OCIAttrGet at (ext\oci8\oci8_statement.c:531) 
OCI8 DEBUG: OCIAttrGet at (ext\oci8\oci8_statement.c:541) 
OCI8 DEBUG: OCIDescriptorFree at (ext\oci8\oci8_statement.c:549) 
OCI8 DEBUG: OCIDefineByPos at (ext\oci8\oci8_statement.c:654) 
OCI8 DEBUG: OCIDefineDynamic at (ext\oci8\oci8_statement.c:697) 
OCI8 DEBUG: OCIStmtFetch at (ext\oci8\oci8_statement.c:146) 
OCI8 DEBUG: OCIDescriptorAlloc at (ext\oci8\oci8_lob.c:75) 
OCI8 DEBUG: OCILobGetLength at (ext\oci8\oci8_lob.c:127) 
OCI8 DEBUG: OCILobCharSetId at (ext\oci8\oci8_lob.c:291) 
OCI8 DEBUG: OCINlsNumericInfoGet at (ext\oci8\oci8_lob.c:305) 
OCI8 DEBUG: OCILobGetChunkSize at (ext\oci8\oci8_lob.c:209) 
OCI8 DEBUG: OCILobRead2 at (ext\oci8\oci8_lob.c:348) 
OCI8 DEBUG: OCILobIsTemporary at (ext\oci8\oci8_lob.c:599) 
OCI8 DEBUG: OCIStmtFetch at (ext\oci8\oci8_statement.c:146) 
OCI8 DEBUG: OCIDescriptorAlloc at (ext\oci8\oci8_lob.c:75) 
OCI8 DEBUG: OCILobGetLength at (ext\oci8\oci8_lob.c:127) 
OCI8 DEBUG: OCILobCharSetId at (ext\oci8\oci8_lob.c:291) 
OCI8 DEBUG: OCINlsNumericInfoGet at (ext\oci8\oci8_lob.c:305) 
OCI8 DEBUG: OCILobGetChunkSize at (ext\oci8\oci8_lob.c:209) 
OCI8 DEBUG: OCILobRead2 at (ext\oci8\oci8_lob.c:348) 
OCI8 DEBUG: OCILobIsTemporary at (ext\oci8\oci8_lob.c:599) 
OCI8 DEBUG: OCIStmtFetch at (ext\oci8\oci8_statement.c:146) 
OCI8 DEBUG: OCIDescriptorAlloc at (ext\oci8\oci8_lob.c:75) 
OCI8 DEBUG: OCILobGetLength at (ext\oci8\oci8_lob.c:127) 
OCI8 DEBUG: OCILobCharSetId at (ext\oci8\oci8_lob.c:291) 
OCI8 DEBUG: OCINlsNumericInfoGet at (ext\oci8\oci8_lob.c:305) 
OCI8 DEBUG: OCILobGetChunkSize at (ext\oci8\oci8_lob.c:209) 
OCI8 DEBUG: OCILobRead2 at (ext\oci8\oci8_lob.c:348) 
OCI8 DEBUG: OCILobIsTemporary at (ext\oci8\oci8_lob.c:599) 
OCI8 DEBUG: OCIStmtFetch at (ext\oci8\oci8_statement.c:146) 
OCI8 DEBUG: OCIStmtRelease at (ext\oci8\oci8_statement.c:723) 
OCI8 DEBUG: OCIHandleFree at (ext\oci8\oci8_statement.c:731) 
OCI8 DEBUG: OCILobIsTemporary at (ext\oci8\oci8_lob.c:599) 
OCI8 DEBUG: OCIDescriptorFree at (ext\oci8\oci8_lob.c:684) 
array(1) {
  ["COLUMN1"]=>
  string(3) "AAA"
}

stop
OCI8 DEBUG: OCILobIsTemporary at (ext\oci8\oci8_lob.c:599) 
OCI8 DEBUG: OCIDescriptorFree at (ext\oci8\oci8_lob.c:684) 
OCI8 DEBUG: OCITransRollback at (ext\oci8\oci8.c:2109) 
OCI8 DEBUG: OCISessionRelease at (ext\oci8\oci8.c:2272) 
OCI8 DEBUG: OCIHandleFree at (ext\oci8\oci8.c:2156) 
OCI8 DEBUG: OCIHandleFree at (ext\oci8\oci8.c:2159) 


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-01-18 21:59 UTC] sixd@php.net
This seems like a duplicate of http://bugs.php.net/bug.php?id=49560
Please test the SVN branch or a snapshot.
 [2010-01-19 09:18 UTC] szymon dot latkowski at geomar dot pl
I'm glad that some work has been done to fix the problem. But I have to pay Your attention to the problem of memory leak. I think that PHP processes does not cmopletely free the memory allocated for object fetching. I've described it in "Actual result" section of this bug. Does the solution for the bug #49560 fixed this problem?
 [2010-01-20 19:15 UTC] sixd@php.net
The destructor code is the same but is now called when there are no 
more references to the LOB, instead of often being deferred to the end 
of the script.
 [2010-01-28 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 [2010-04-25 20:25 UTC] felipe@php.net
-Status: No Feedback +Status: Assigned -Assigned To: +Assigned To: sixd
 [2010-04-26 00:33 UTC] sixd@php.net
-Status: Assigned +Status: No Feedback
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 15:01:29 2024 UTC