FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour ATENTOS. TXMLDocument no libera memoria
Posts: 731
Joined: Fri Oct 07, 2005 07:42 AM
ATENTOS. TXMLDocument no libera memoria
Posted: Wed Jan 28, 2015 04:44 PM

Buenas,

A partir de un servidor Web, uhttp que trae Harbour, el uso de TXMLDocument tiene un MUY GRAVE, y es que NO LIBERA MEMORIA.
Eso lo detecte hace años en xHarbour, pero veo que en Harbour sigue pasando lo mismo.

He pasado a usar minixml, en verdaderamente un engorro, porque tengo todo el sistema con TXMLDocument, y cuesta volver a usar
funciones ;-(

La pruebas son espectaculares, 100.000 peticiones , 10 hilos corriendo contra el server en un minuto, y pequeño XML que se devuelve, minixml consume 1 mega.
Lo mismo con TXMLDocument se va a 1.3GIGAS de RAM!!!!

Lo dicho, OJO con esta librería, no sé si la ha corregido, pero si puedo montar un ejemplo y atacarlo , a ver si son capaces de ver donde esta el fallo

Saludos Cordiales

Saludos

Rafa Carmona ( rafa.thefullARROBAgmail.com___quitalineas__)
Posts: 731
Joined: Fri Oct 07, 2005 07:42 AM
Re: ATENTOS. TXMLDocument no libera memoria
Posted: Wed Jan 28, 2015 05:39 PM
Bueno, ya tengo el ejemplo que demuestra consumo excesivo de memoria...

Para probarlo, usar una herramienta tipo SoapUI para hacer peticiones masivas...
Despues, tenemos la llamada;
http://127.0.0.1:1092/xml_mini el cual nos devuelve un XML usando la libreria MiniXML
http://127.0.0.1:1092/xml_doc el cual nos devuelve un XML usando la clase TXMLDocument

Resultados de las pruebas de estres;
MINIXML--> Empiezo con 2 Megas de RAM, 7 hilos simultanios -+ 100.000 peticiones --> Se queda el programa con un consumo de memoria de 4.7 MB
TXMLDoc-->Empiezo con 2 Megas de RAM, 7 hilos simultanios -+ 100.000 peticiones --> Se queda el programa con un consumo de memoria de 80.6 MB!!!!!

Este es el XML que se retorna en los 2 casos
<SetConceptoHotelPMSRS CODIGOHOT="">
<CONCEPTO PAX="1"/>
<CONCEPTO PAX="2"/>
<CONCEPTO PAX="3"/>
<CONCEPTO PAX="4"/>
<CONCEPTO PAX="5"/>
<CONCEPTO PAX="6"/>
<CONCEPTO PAX="7"/>
<CONCEPTO PAX="8"/>
<CONCEPTO PAX="9"/>
<CONCEPTO PAX="10"/>
</SetConceptoHotelPMSRS>

Dejo el codigo fuente, para a ver si alguien puede corroborar esto;
Code (fw): Select all Collapse
#
# $Id: hbmk.hbm
#
hbssl.hbc
hbhttpd.hbc
hbblink.hbc
hbwin.hbc
hbmxml.hbc

-lxhb -lgtwin -lgtwvg -lgtgui -lhbwin -lhbmisc -lhbxpp -lhbct 
-ic:\programacion\harbour3\contrib\xhb

-oserver.exe
-w0
-es1
-mt

test.prg


Code (fw): Select all Collapse
// t:\harbour3\bin\hbmk2 
#include "hbthread.ch"
#include "Hblog.ch"
#include "hbdll.ch"

STATIC s_hMutex
STATIC s_lLog4Harbour := .T.

MEMVAR get, post, server

FUNCTION HB_GTSYS()
   REQUEST HB_GT_WVT_DEFAULT
RETURN NIL

/*---------------------------------------------------------------------------------------------*/
/* Entrada al servidor WEB */
/*---------------------------------------------------------------------------------------------*/

#include "fileio.ch"

FUNCTION Main( cParam1, cParam2 )
   LOCAL lMutex
   LOCAL n := 0
   Local lCreateThread := hb_mtvm() 

   if lCreateThread
      run_web()
   endif   
    
   hb_MemoWrit( ".uhttpd.stop", "" )  // ESTO PARA el servidor WEB


RETURN

  
#require "hbssl"
#require "hbhttpd"

/*---------------------------------------------------------------------------------------------*/
procedure run_web( )

   LOCAL oServer

   LOCAL oLogAccess
   LOCAL oLogError

   LOCAL nPort := 1092
   

   IF hb_argCheck( "stop" )
      hb_MemoWrit( ".uhttpd.stop", "" )
      RETURN
   ELSE
      FErase( ".uhttpd.stop" )
   ENDIF

   oLogAccess := UHttpdLog():New( hb_dirBase() +"web_access.log" )

   IF ! oLogAccess:Add( "" )
      oLogAccess:Close()
      RETURN
   ENDIF

   oLogError := UHttpdLog():New( hb_dirBase() +"web_error.log" )
   
   IF ! oLogError:Add( "" )
      oLogError:Close()
      oLogAccess:Close()
      RETURN
   ENDIF

   oServer := UHttpdNew()

   IF ! oServer:Run( { ;
         "FirewallFilter"      => "", ;
         "LogAccess"           => {| m | oLogAccess:Add( CStr( m  )+ hb_eol() ) }, ;
         "LogError"            => {| m | oLogError:Add( Cstr( m  )+ hb_eol() ) }, ;
         "Trace"               => {| ... | QOut( ... ) }, ;
         "Port"                => nPort, ;
         "Idle"                => {| o | iif( hb_FileExists( ".uhttpd.stop" ), ( FErase( ".uhttpd.stop" ), o:Stop() ), NIL ) }, ;
         "SSL"                 => .F.,;
         "Mount"          => { ;
             "/info"             => {|| informarcion() }, ;
             "/xml_mini"         => {|| play_xml() }, ;
             "/xml_doc"          => {|| play_doc() }, ;
             "/"                 => {|| UWrite( "Hello!" ) } } } )

      oLogError:Close()
      oLogAccess:Close()
      ErrorLevel( 1 )
      RETURN 
   ENDIF
 
   oLogError:Close()
   oLogAccess:Close()

   RETURN

/*
 Devuelve información del Entorno
*/
static function informarcion()
       UWrite( '<h2>Version Test : '+ "df_Version" +'</h2>' ) 
return UProcInfo() 



// --------------------------------------------------------------------------------//
// Usando MiniXML apenas se nota consumo de memoria.
// --------------------------------------------------------------------------------//
function play_xml() 
  local xml, cStr := space( 100000 ), data, htree, x 
  
  xml := mxmlNewXML("1.0")
  data = mxmlNewElement(xml, "SetConceptoHotelPMSRS")
         mxmlElementSetAttr( data, "CODIGOHOT", "" )

  for x := 1 to 10
    hTree = mxmlNewElement( data, "CONCEPTO" )
         mxmlElementSetAttr( htree, "PAX", alltrim( Cstr( x ) ) )
  next       
  
  mxmlSaveString( xml , @cStr )
  mxmlDelete( xml )

  UAddHeader( "Content-Type", "text/xml;charset=utf-8" )

return UWrite( cStr )




// --------------------------------------------------------------------------------//
// Usando TXMLDOC grave problema de memoria
// --------------------------------------------------------------------------------//

#include "hbclass.ch"
#include "hbxml.ch"

function play_doc(  )
   Local oTarifas
   Local cEncoding := "ISO-8859-1"

   
   oTarifas := Twebtarifas():New()
   for x := 1 to 10 
       oTarifas:Append( X )
   next

   UAddHeader( "Content-Type", "text/xml;charset=utf-8" )
   UWrite( oTarifas:WriteXML() )

RETURN nil



// --------------------------------------------------------------------------------//
// --------------------------------------------------------------------------------//
CLASS TGeneric
      DATA CodigoHot  INIT ""
      DATA IDUSER INIT "0"
      DATA oDoc
      DATA lUTF8 INIT .F.

ENDCLASS


// --------------------------------------------------------------------------------//
// --------------------------------------------------------------------------------//
CLASS Twebtarifas from TGeneric
      DATA aTarifas
    
      DATA Operacion   INIT "SetConceptoHotelPMSRS"

      METHOD New() CONSTRUCTOR
      METHOD WriteXML()
      METHOD Append( cCodigo, cDescripcion  )
      METHOD CreateXML()

ENDCLASS

// --------------------------------------------------------------------------------//
METHOD New( ) CLASS Twebtarifas
   ::aTarifas := {}
RETURN Self

METHOD CreateXML( ) CLASS Twebtarifas
Local oNode, oNodeP, oRes

    cEncoding := "UTF-8"
   ::oDoc := TXmlDocument():New() // Creacion del documento respuesta....
   ::oDoc:oRoot:AddBelow( TxmlNode():New( HBXML_TYPE_PI,'xml' , , 'version="1.0" encoding="'+ cEncoding +'" ' ) )

RETURN ::oDoc:oRoot


// --------------------------------------------------------------------------------//
METHOD WriteXML() CLASS Twebtarifas
   Local oNode, oNodeP, oNodeConcepto, aTarifa

   oNode := ::CreateXML()

   oNodeP := TxmlNode():New( HBXML_TYPE_TAG, ::Operacion  )
             oNodeP:SetAttribute( "CODIGOHOT", ::CodigoHot )
             oNodeP:SetAttribute( "IDUSER",    ::IdUser )

   oNode:AddBelow( oNodeP )

   if !empty( ::aTarifas )
      for each aTarifa in ::aTarifas
          oNodeConcepto := TxmlNode():New( HBXML_TYPE_TAG, "CONCEPTO" )
             oNodeConcepto:SetAttribute( "PAX",      UHtmlEncode( aTarifa[1] ) )
          oNodeP:AddBelow( oNodeConcepto )
      next
   endif

RETURN ::oDoc:ToString()

METHOD Append( nPax ) CLASS Twebtarifas
  AADD( ::aTarifas, { alltrim( Cstr( nPax ) ) } )
RETURN NIL
Saludos

Rafa Carmona ( rafa.thefullARROBAgmail.com___quitalineas__)
Posts: 8515
Joined: Tue Dec 20, 2005 07:36 PM
Re: ATENTOS. TXMLDocument no libera memoria
Posted: Wed Jan 28, 2015 05:41 PM
Mismo usando uno de estes comandos?

Code (fw): Select all Collapse
   globalNode  = null

   xmldoc = null

   oxml := nil

   hb_gcall(.t.)


Saludos.
João Santos - São Paulo - Brasil - Phone: +55(11)95150-7341
Posts: 731
Joined: Fri Oct 07, 2005 07:42 AM
Re: ATENTOS. TXMLDocument no libera memoria
Posted: Wed Jan 28, 2015 05:53 PM

Buenos , si es lo primero que se hice... lo mismo, es más, como pongas hb_gcall() en un hilo, cruje hasta Windows...
Porque no puedo subir una imagen, foto que lo demuestra, ;-), pero GPFs en Windows 7.

Saludos

Rafa Carmona ( rafa.thefullARROBAgmail.com___quitalineas__)
Posts: 8515
Joined: Tue Dec 20, 2005 07:36 PM
Re: ATENTOS. TXMLDocument no libera memoria
Posted: Wed Jan 28, 2015 06:10 PM

Discúlpas,

No sé lo que significa Hilo.

Saludos.

João Santos - São Paulo - Brasil - Phone: +55(11)95150-7341
Posts: 8515
Joined: Tue Dec 20, 2005 07:36 PM
Re: ATENTOS. TXMLDocument no libera memoria
Posted: Wed Jan 28, 2015 06:16 PM
Intentas:

Code (fw): Select all Collapse
METHOD CreateXML( ) CLASS Twebtarifas

   Local oNode, oNodeP, oRes

   HB_GCALL( .F. ) // limpia basuras .T. fuerza

   cEncoding := "UTF-8"

   ::oDoc := TXmlDocument():New() // Creacion del documento respuesta....
   ::oDoc:oRoot:AddBelow( TxmlNode():New( HBXML_TYPE_PI,'xml' , , 'version="1.0" encoding="'+ cEncoding +'" ' ) )

RETURN ::oDoc:oRoot


// --------------------------------------------------------------------------------//
METHOD WriteXML() CLASS Twebtarifas

   Local oNode, oNodeP, oNodeConcepto, aTarifa

   HB_GCALL( .F. ) // limpia basuras .T. fuerza

   oNode := ::CreateXML()

   oNodeP := TxmlNode():New( HBXML_TYPE_TAG, ::Operacion  )
             oNodeP:SetAttribute( "CODIGOHOT", ::CodigoHot )
             oNodeP:SetAttribute( "IDUSER",    ::IdUser )

   oNode:AddBelow( oNodeP )

   if !empty( ::aTarifas )
      for each aTarifa in ::aTarifas
          oNodeConcepto := TxmlNode():New( HBXML_TYPE_TAG, "CONCEPTO" )
             oNodeConcepto:SetAttribute( "PAX",      UHtmlEncode( aTarifa[1] ) )
          oNodeP:AddBelow( oNodeConcepto )
      next
   endif

RETURN ::oDoc:ToString()


Saludos

João Santos - São Paulo - Brasil - Phone: +55(11)95150-7341
Posts: 1515
Joined: Thu Oct 30, 2008 02:37 PM
Re: ATENTOS. TXMLDocument no libera memoria
Posted: Wed Jan 28, 2015 06:46 PM

Y... ¿ No se debería trasladar este problema a la lista de desarrollo de harbour ? (https://groups.google.com/forum/?fromgr ... bour-devel)

Posts: 731
Joined: Fri Oct 07, 2005 07:42 AM
Re: ATENTOS. TXMLDocument no libera memoria
Posted: Thu Jan 29, 2015 10:42 AM

Si , pero para no hacer perder el tiempo a los desarrolladores, primero intento hacer pruebas, mirar si nos pasa a todos lo mismo, en sus variantes.

Aqui la info, con las imagenes sobre el tema

http://xthefull.blogspot.com.es/2015/01 ... emory.html

http://xthefull.blogspot.com.es/2015/01 ... pdate.html

Saludos

Rafa Carmona ( rafa.thefullARROBAgmail.com___quitalineas__)
Posts: 731
Joined: Fri Oct 07, 2005 07:42 AM
Re: ATENTOS. TXMLDocument no libera memoria
Posted: Thu Jan 29, 2015 11:04 AM
karinha wrote:Intentas:
/quote]

Llamando manualmente a HB_GCALL( .F. ) , los picos de consumo y limpieza del recoletor de memoria es terrible, pero lo deja en 5Mb RAM.

Ahora, si le meto otra llamada en el código ;
Code (fw): Select all Collapse
function play_doc(  )
   Local oTarifas
   Local cEncoding := "ISO-8859-1"

   
   oTarifas := Twebtarifas():New()
   for x := 1 to 10 
       oTarifas:Append( X )
   next

   UAddHeader( "Content-Type", "text/xml;charset=utf-8" )
   UWrite( oTarifas:WriteXML() )
  

   oTarifas := NIL
   HB_GCALL( .F. ) // limpia basuras .T. fuerza

RETURN nil


En consumo vuelve a bajar a 4.7Mb, más o menos como la miniXML.
Pero la diferencia, es que la minixml es progresivo en el consumo de memoria, TXMLDocument mete unos picos de consumo, llega a 8Megas RAM y un descenso tremendos.

Lo que no entiendo es porque NO BAJA el consumo de memoria, siempre se SUMA, y a la larga, el programa tiene que ser reiniciado por el excesivo consumo de RAM.

Seguiré investigando..
Saludos

Rafa Carmona ( rafa.thefullARROBAgmail.com___quitalineas__)
Posts: 731
Joined: Fri Oct 07, 2005 07:42 AM
Re: ATENTOS. TXMLDocument no libera memoria
Posted: Thu Jan 29, 2015 01:17 PM

Dios mio, sigo perdiendo memoria a marchas forzadas, al punto que se reinicia la maquina ;-(

En el test, con respecto a mi código , es que recorro una tabla y se crea el xml a partir de la tabla, además de estar como servicio.
Intentaré que recorra una tabla y ver si por ahí está el problema.

Saludos Cordiales

Saludos

Rafa Carmona ( rafa.thefullARROBAgmail.com___quitalineas__)
Posts: 990
Joined: Thu Nov 17, 2005 05:49 PM
Re: ATENTOS. TXMLDocument no libera memoria
Posted: Fri Jan 30, 2015 12:05 AM
Rafa;

Hace algún tiempo me di con este problema, pero luego de reportarlo en el foro de xharbour, el problema quedó arreglado. Este es un enlace al hilo donde se atiende el tema:

https://groups.google.com/forum/#!topic/comp.lang.xharbour/8fd5ZzKxhDI

Reinaldo.
Posts: 731
Joined: Fri Oct 07, 2005 07:42 AM
Re: ATENTOS. TXMLDocument no libera memoria
Posted: Fri Jan 30, 2015 09:43 AM

Muchas gracias Reinaldo
>Better still, move these variables to the PRIVATE DATA section of the CLASS.
No se a que se refiere con esta solución.

¿ Esta es la solución que corrige el problema ? ¿ O era un problema de xHarbour ?
Si es de xHarbour, ¿ has probado si con Harbour te da el mismo problema que tenias ?

De momento, como estoy al inicio del nuevo proyecto, me decanto a usar mxml , no me gusta el tema de
volver a usar funciones, pero bueno, si no falla , es lo único que ahora me importa.

Saludos Cordiales

Saludos

Rafa Carmona ( rafa.thefullARROBAgmail.com___quitalineas__)
Posts: 8515
Joined: Tue Dec 20, 2005 07:36 PM
Re: ATENTOS. TXMLDocument no libera memoria
Posted: Fri Jan 30, 2015 12:00 PM
Tal vez:

Code (fw): Select all Collapse
   REQUEST HB_MEMIO
João Santos - São Paulo - Brasil - Phone: +55(11)95150-7341
Posts: 990
Joined: Thu Nov 17, 2005 05:49 PM
Re: ATENTOS. TXMLDocument no libera memoria
Posted: Fri Jan 30, 2015 02:57 PM

Rafa;

Es cierto que el hilo tiene sugerencias tontas que nada tienen que ver con el problema, como por ejemplo esa que mencionas. Pero al final del hilo Saulius menciona que deja el problema de memory leak corregido en el build 9920 de xharbour. Luego busqué el change log del build 9920 y pude ver mas detalle de que fue lo que hicieron. Han pasado 2 años, ya ni lo recuerdo pero tenía que ver con el release de memoria una vez se destruye un objeto TxmlDocument(). No he probado con Harbour. Siento mucho que ya no recuerdo detalles sobre el tema. Lo que si te puedo asegurar es que ya no tengo el memory-leak que antes tenía con el continuo uso de TxmDocument() y es por eso que decidí participar en este hilo.

Hope that helps,

Reinaldo.

Posts: 731
Joined: Fri Oct 07, 2005 07:42 AM
Re: ATENTOS. TXMLDocument no libera memoria
Posted: Fri Jan 30, 2015 05:11 PM

Muchas gracias Reinaldo, hace mucho tiempo dejo xHarbour, pero NO me parece normal que tengamos que FORZAR nosotros a entrar el recolector de basura.
De todas, por si te interesa, me ha costado un poco entender como funciona esta librería a la hora de recorrer un xml ;-)

http://xthefull.blogspot.com.es/2015/01 ... -mxml.html

Saludos

Rafa Carmona ( rafa.thefullARROBAgmail.com___quitalineas__)