|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
[2001-03-08 12:48 UTC] stas@php.net
[2001-04-10 09:37 UTC] sniper@php.net
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Sat Oct 25 13:00:01 2025 UTC |
Hi there, as there are no extentions returning objects, perhaps I am the first to encounter following problem: I wrote an extention with functions returning objects. The problem is that these objects are not automatically destroyed in memory when no variable references them anymore. A script like the following causes php to consume more and more memory until it terminates with "out of memory" ... 01:<? 02: [...] 03: while ($i++ < 10000) 04: { 05: $result=k2_searchrecv($a,$b,$c,$d,$e); 06: } 07: [...] 08: 09:?> Even if I change line 05 to 05: k2_searchrecv($a,$b,$c,$d,$e); so that the resulting object is not referenced by any variable, memory consumption grows. one resulting objects looks like: object(stdClass)(9) { ["errorCode"]=> int(0) ["errorMessage"]=> string(1) "-" ["docStart"]=> int(1) ["docPage"]=> int(6) ["numHit"]=> int(6) ["numProc"]=> int(52672) ["numCols"]=> int(3) ["numRows"]=> int(6) ["square"]=> array(6) { [0]=> object(stdClass)(3) { ["SCORE"]=> string(6) "0.7742" ["VdkVgwKey"]=> string(6) "401824" ["JOB_TITLE"]=> string(44) "Software-Entwickler/in Information Retrieval" } [1]=> object(stdClass)(3) { ["SCORE"]=> string(6) "0.7742" ["VdkVgwKey"]=> string(6) "384327" ["JOB_TITLE"]=> string(18) "UNIX-Administrator" } [2]=> object(stdClass)(3) { ["SCORE"]=> string(6) "0.7742" ["VdkVgwKey"]=> string(6) "396529" ["JOB_TITLE"]=> string(38) "SoftwareentwicklerInnen-architektInnen" } [3]=> object(stdClass)(3) { ["SCORE"]=> string(6) "0.7742" ["VdkVgwKey"]=> string(6) "314928" ["JOB_TITLE"]=> string(27) "Anwendungsprogrammierer(in)" } [4]=> object(stdClass)(3) { ["SCORE"]=> string(6) "0.7742" ["VdkVgwKey"]=> string(8) "10017461" ["JOB_TITLE"]=> string(41) "Praktikant oder studentischer Mitarbeiter" } [5]=> object(stdClass)(3) { ["SCORE"]=> string(6) "0.7742" ["VdkVgwKey"]=> string(6) "239921" ["JOB_TITLE"]=> string(38) "Internet/Intranet/Extranet-Consultants" } } } Could the problem be, that the object-type is stdClass and not a user-defined class ? Here one function that builds an object as result: ------------------------------------------------------------ PHP_FUNCTION(k2_searchrecv) { zval **shandle, **docstart, **docpage, **timeout, **fieldnames; zval **ksquare=0 ,***dummyzval=0 ; K2Error kerror; char *dummyptr; char **fieldnamearray = 0; int i,j; int fieldcount; int withfieldnames = 0; int retries = 0; char *dummystring; K2SearchRecvOut recvOut = 0; K2SearchRecvArgRec recvNew; switch(ZEND_NUM_ARGS()) { case 4: { if (zend_get_parameters_ex(4, &shandle, &docstart, &docpage, &timeout) == FAILURE) RETURN_LONG(-1); break;} case 5: { if (zend_get_parameters_ex(5, &shandle, &docstart, &docpage, &timeout, &fieldnames) == FAILURE) RETURN_LONG(-1); withfieldnames = 1; dummystring = estrdup((*fieldnames)->value.str.val); fieldcount = k2_internal_getNoOfStrings(dummystring); dummyptr = dummystring; fieldnamearray=(char**) emalloc (sizeof(char*) * fieldcount); if (fieldnamearray == NULL) { php_error(E_ERROR,"k2_searchrecv: Unable to allocate memory for 'fieldnamearray'"); return; } for (j=0; j < fieldcount; j++) { fieldnamearray[j]=estrdup(dummyptr); dummyptr = dummyptr + strlen(dummyptr)+1; } efree(dummystring); break;} default: WRONG_PARAM_COUNT; } convert_to_long_ex(shandle); convert_to_long_ex(docstart); convert_to_long_ex(docpage); convert_to_long_ex(timeout); K2StructInit(&recvNew); recvNew.docStart = (*docstart)->value.lval; recvNew.docPage = (*docpage)->value.lval; recvNew.timeout = (*timeout)->value.lval; if ((kerror=K2SearchRecv((K2Search)(*shandle)->value.lval,&recvNew,&recvOut)) != K2Success) { if (kerror == 1) { usleep(100); while ((kerror=K2SearchRecv((K2Search)(*shandle)->value.lval,&recvNew,&recvOut) != K2Success) && (retries < MAX_RETRIES)) { usleep(100); retries++; } } if (kerror != K2Success) RETURN_LONG(kerror); } if (object_init(return_value) == FAILURE) { php_error(E_ERROR, "k2_searchrecv: Unable to initialize 'return_value' as object"); return -1; } add_property_long(return_value,"errorCode", recvOut->errorCode); if (recvOut->errorMessage) { add_property_string(return_value,"errorMessage",recvOut->errorMessage,1); } else { add_property_string(return_value,"errorMessage","-",1); } add_property_long(return_value,"docStart",recvOut->docStart); add_property_long(return_value,"docPage",recvOut->docPage); add_property_long(return_value,"numHit",recvOut->numHit); add_property_long(return_value,"numProc",recvOut->numProc); if (recvOut->square) { add_property_long(return_value,"numCols",recvOut->square->numCols); add_property_long(return_value,"numRows",recvOut->square->numRows); ksquare = (zval **) emalloc (sizeof(zval*)); dummyzval = (zval ***) emalloc(sizeof(zval**)); *dummyzval = (zval *) emalloc(sizeof(zval *)); *ksquare = (zval*) emalloc (sizeof(zval)); if ( array_init(*ksquare) == FAILURE ) { php_error(E_ERROR,"k2_searchrecv: Unable to initialize '*ksquare' as object"); return; } dummyptr = (char*) recvOut->square->pData; for(i=0; i < recvOut->square->numRows; i++) { // create one element of the result list including all specified fields *dummyzval=(zval**) emalloc(sizeof(zval*)); **dummyzval= (zval*) emalloc(sizeof(zval)); if (**dummyzval == NULL) { php_error(E_ERROR, "k2_searchrecv: Unable to allocate memory for '**dummyzval'"); } if (withfieldnames == 0) { if (array_init(**dummyzval) == FAILURE) { php_error(E_ERROR, "k2_searchrecv: Unable to initialize '**dummyzval' as array"); return; } } else { if (object_init(**dummyzval) == FAILURE) { php_error(E_ERROR, "k2_searchrecv: Unable to initialize '**dummyzval' as object"); return; } } for(j=0; j < recvOut->square->numCols; j++) { if (withfieldnames == 0) { add_next_index_string(**dummyzval,dummyptr,1);} else {add_property_string(**dummyzval,fieldnamearray[j],dummyptr,1);} // printf("%d: %p[%d] -> %s \n",i,**dummyzval,j,dummyptr); dummyptr = dummyptr + strlen(dummyptr) + 1; //printf("j=%d - %s\n",j,dummyptr); } // append zend_hash_next_index_insert((*ksquare)->value.ht,*dummyzval,sizeof(zval*),NULL); } // append all the results in ksquare to the return structure zend_hash_add(return_value->value.obj.properties,"square",strlen("square")+1, (void*) ksquare,sizeof (zval*),NULL); } else { add_property_long(return_value,"numCols",0); add_property_long(return_value,"numRows",0); } //clean up K2SearchRecvFree(recvOut); if (withfieldnames) { for (i=0; i < fieldcount; i++) efree(fieldnamearray[i]); efree(fieldnamearray); } } ------------------------------------------------------------ TIA CHristian