Hola,
El método QueryRow de tAdoDatasource presenta un problema de consumo de
memoria que, en aplicaciones que hace un uso extensivo de este método, hace
que la aplicación deje sin memoria física al sistema operativo.
Por ejemplo:
For n := 1 TO 1000
a := ::oAdoDataSource1:QueryRow("SELECT * FROM miTabla WHERE miWhere =
1")
NEXT
Produce una pérdida de memoria de irrecuperable (no he visto el modo de
recuperarlo). Este problema lo hemos detectado en nuestras aplicaciones que
están funcionando 24/7 y hacen un uso moderado de este método.
El caso es que parece ser que tOleAuto de xHarbour junto con FOR EACH son
altamente ineficientes en la gestión de memoria. Quizás habría que hablar
con la gente de xharbour para ver como lo solucionan.
Os propongo lo siguiente para corregir ese problema:
METHOD QueryRow( cCommand, aHeaders, aDefault ) CLASS XAdoDataSource
LOCAL oRS, oError, oField
LOCAL aBuffer, aFields
LOCAL nFor, nFields, n
LOCAL a
DEFAULT aDefault TO {}
IF ! ::CheckConnection()
RETURN {}
ENDIF
aBuffer := {}
TRY
oRS := TOleAuto():New( "ADODB.RecordSet" )
CATCH oError
::NewError( oError:Description, oError:SubCode,, "ADODB:RecordSet" )
END
TRY
oRS:MaxRecords := 1
CATCH
END
TRY
oRS:Open( cCommand, ::oConnection, adOpenForwardOnly, adLockReadOnly,
adCmdText )
CATCH oError
::NewADOError( "ADODB:RecordSet:Open( '" + cCommand+ "' )" )
oRS := NIL
RETURN aDefault
END
WITH OBJECT oRS
nFields := :Fields:Count
IF !:Eof() .AND. !:Bof()
:MoveFirst()
aBuffer := Array( nFields )
FOR n := 0 TO nFields -1
aBuffer[ n+1 ] := :Fields(n):Value
NEXT
ENDIF
IF Pcount() > 1
aHeaders := Array( nFields )
FOR EACH oField IN :Fields
aHeaders[ HB_EnumIndex() ] := oField:Name
NEXT
ENDIF
:Close()
END WITH
oRS := NIL
RETURN IIf( Empty( aBuffer ), aDefault, aBuffer )
Saludos,
José Luis Capel
In order for this site to work correctly we need to store a small file (called a cookie) on your computer. Most every site in the world does this, however since the 25th of May 2011, by law we have to get your permission first. Please abandon the forum if you disagree.
Para que este foro funcione correctamente es necesario guardar un pequeño fichero (llamado cookie) en su ordenador. La mayoría de los sitios de Internet lo hacen, no obstante desde el 25 de Marzo de 2011 y por ley, necesitamos de su permiso con antelación. Abandone este foro si no está conforme.
Para que este foro funcione correctamente es necesario guardar un pequeño fichero (llamado cookie) en su ordenador. La mayoría de los sitios de Internet lo hacen, no obstante desde el 25 de Marzo de 2011 y por ley, necesitamos de su permiso con antelación. Abandone este foro si no está conforme.
Problema de consumo de memoria tOleAuto|QueryRow
- ignacio
- Site Admin
- Mensajes: 9459
- Registrado: Lun Abr 06, 2015 8:00 pm
- Ubicación: Madrid, Spain
- Contactar:
Problema de consumo de memoria tOleAuto|QueryRow
José Luis,
Hecho. El cambio ha sido mínimo y si a ti te deja de consumir memoria
seguro que efectivamente será un error de xHarbour.
Un saludo
Ignacio Ortiz de Zúñiga
[Equipo de Xailer / Xailer team]
http://www.xailer.com
http://www.xailer.info
http://www.xailer.com/forum
http://www.xailer.com/dokuwiki
"José Luis Capel" escribió en el mensaje de
noticias:4d2488f7$[email=1@svctag-j7w3v3j....]1@svctag-j7w3v3j....[/email]
Hola,
El método QueryRow de tAdoDatasource presenta un problema de consumo de
memoria que, en aplicaciones que hace un uso extensivo de este método, hace
que la aplicación deje sin memoria física al sistema operativo.
Por ejemplo:
For n := 1 TO 1000
a := ::oAdoDataSource1:QueryRow("SELECT * FROM miTabla WHERE miWhere =
1")
NEXT
Produce una pérdida de memoria de irrecuperable (no he visto el modo de
recuperarlo). Este problema lo hemos detectado en nuestras aplicaciones que
están funcionando 24/7 y hacen un uso moderado de este método.
El caso es que parece ser que tOleAuto de xHarbour junto con FOR EACH son
altamente ineficientes en la gestión de memoria. Quizás habría que hablar
con la gente de xharbour para ver como lo solucionan.
Os propongo lo siguiente para corregir ese problema:
METHOD QueryRow( cCommand, aHeaders, aDefault ) CLASS XAdoDataSource
LOCAL oRS, oError, oField
LOCAL aBuffer, aFields
LOCAL nFor, nFields, n
LOCAL a
DEFAULT aDefault TO {}
IF ! ::CheckConnection()
RETURN {}
ENDIF
aBuffer := {}
TRY
oRS := TOleAuto():New( "ADODB.RecordSet" )
CATCH oError
::NewError( oError:Description, oError:SubCode,, "ADODB:RecordSet" )
END
TRY
oRS:MaxRecords := 1
CATCH
END
TRY
oRS:Open( cCommand, ::oConnection, adOpenForwardOnly, adLockReadOnly,
adCmdText )
CATCH oError
::NewADOError( "ADODB:RecordSet:Open( '" + cCommand+ "' )" )
oRS := NIL
RETURN aDefault
END
WITH OBJECT oRS
nFields := :Fields:Count
IF !:Eof() .AND. !:Bof()
:MoveFirst()
aBuffer := Array( nFields )
FOR n := 0 TO nFields -1
aBuffer[ n+1 ] := :Fields(n):Value
NEXT
ENDIF
IF Pcount() > 1
aHeaders := Array( nFields )
FOR EACH oField IN :Fields
aHeaders[ HB_EnumIndex() ] := oField:Name
NEXT
ENDIF
:Close()
END WITH
oRS := NIL
RETURN IIf( Empty( aBuffer ), aDefault, aBuffer )
Saludos,
José Luis Capel
Hecho. El cambio ha sido mínimo y si a ti te deja de consumir memoria
seguro que efectivamente será un error de xHarbour.
Un saludo
Ignacio Ortiz de Zúñiga
[Equipo de Xailer / Xailer team]
http://www.xailer.com
http://www.xailer.info
http://www.xailer.com/forum
http://www.xailer.com/dokuwiki
"José Luis Capel" escribió en el mensaje de
noticias:4d2488f7$[email=1@svctag-j7w3v3j....]1@svctag-j7w3v3j....[/email]
Hola,
El método QueryRow de tAdoDatasource presenta un problema de consumo de
memoria que, en aplicaciones que hace un uso extensivo de este método, hace
que la aplicación deje sin memoria física al sistema operativo.
Por ejemplo:
For n := 1 TO 1000
a := ::oAdoDataSource1:QueryRow("SELECT * FROM miTabla WHERE miWhere =
1")
NEXT
Produce una pérdida de memoria de irrecuperable (no he visto el modo de
recuperarlo). Este problema lo hemos detectado en nuestras aplicaciones que
están funcionando 24/7 y hacen un uso moderado de este método.
El caso es que parece ser que tOleAuto de xHarbour junto con FOR EACH son
altamente ineficientes en la gestión de memoria. Quizás habría que hablar
con la gente de xharbour para ver como lo solucionan.
Os propongo lo siguiente para corregir ese problema:
METHOD QueryRow( cCommand, aHeaders, aDefault ) CLASS XAdoDataSource
LOCAL oRS, oError, oField
LOCAL aBuffer, aFields
LOCAL nFor, nFields, n
LOCAL a
DEFAULT aDefault TO {}
IF ! ::CheckConnection()
RETURN {}
ENDIF
aBuffer := {}
TRY
oRS := TOleAuto():New( "ADODB.RecordSet" )
CATCH oError
::NewError( oError:Description, oError:SubCode,, "ADODB:RecordSet" )
END
TRY
oRS:MaxRecords := 1
CATCH
END
TRY
oRS:Open( cCommand, ::oConnection, adOpenForwardOnly, adLockReadOnly,
adCmdText )
CATCH oError
::NewADOError( "ADODB:RecordSet:Open( '" + cCommand+ "' )" )
oRS := NIL
RETURN aDefault
END
WITH OBJECT oRS
nFields := :Fields:Count
IF !:Eof() .AND. !:Bof()
:MoveFirst()
aBuffer := Array( nFields )
FOR n := 0 TO nFields -1
aBuffer[ n+1 ] := :Fields(n):Value
NEXT
ENDIF
IF Pcount() > 1
aHeaders := Array( nFields )
FOR EACH oField IN :Fields
aHeaders[ HB_EnumIndex() ] := oField:Name
NEXT
ENDIF
:Close()
END WITH
oRS := NIL
RETURN IIf( Empty( aBuffer ), aDefault, aBuffer )
Saludos,
José Luis Capel
Ignacio Ortiz de Zúñiga
[OZ Software]
https://www.ozs.es
--
[Equipo de Xailer / Xailer team]
https://www.xailer.com
[OZ Software]
https://www.ozs.es
--
[Equipo de Xailer / Xailer team]
https://www.xailer.com