viernes, 27 de febrero de 2015

Usando CreateObject(). No se libera memoria


Batallando en la creacion de un webservices, quería poner un validador de XSD,
de esta manera, el recibir un XML, podemos ver si cumple o no cumple.

Lo curioso es que me dio por ver como va de rendimiento y me topo otra vez con el problema de la memoria.

En la primera imagen, se muestra la memoria antes del bucle, 1.8Mb;



En segunda, imagen , después del test , 100 llamadas ,tenemos un consumo de 7.2Mb :




He aquí el test para que podais ver si os paso a vosotros.

/* Show not liberate memory */
FUNCTION HB_GTSYS()
   REQUEST HB_GT_WVT_DEFAULT
   REQUEST HB_GT_WIN
   REQUEST HB_LANG_ES
RETURN NIL

Function Main()

    Alert( "Begin...")

    for x := 1 to 100
        ? _Validate_XSD()
    next
   
    Alert( "Finish")

return

function  _Validate_XSD( )
   Local oXmlDoc, oSchema, oSchemaCache, oParseError
   Local lOk := .f.
   Local cMensaje
   Local cString_XSD := [<?xml version="1.0" encoding="UTF-8"?><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xs:element name="GetInfoRQ">   <xs:annotation>     <xs:documentation>Devolvemos información de kiosko</xs:documentation>   </xs:annotation>    <xs:complexType>      <xs:attribute name="HotelID" type="xs:int" use="required">        <xs:annotation>         <xs:documentation>ID del Hotel</xs:documentation>       </xs:annotation>      </xs:attribute>     <xs:attribute name="StationID" type="xs:string" use="required">       <xs:annotation>         <xs:documentation>ID del Kiiosko</xs:documentation>       </xs:annotation>      </xs:attribute>     <xs:attribute name="UserID">        <xs:annotation>         <xs:documentation>Usuario:password que realiza la peticion</xs:documentation>       </xs:annotation>      </xs:attribute>   </xs:complexType> </xs:element></xs:schema> ]


   Local cString_XML := [<?xml version="1.0" encoding="UTF-8"?><GetInfoRQ HotelID="1a2" StationID="1" ></GetInfoRQ>]
  
   oXmlDoc := CreateObject("Msxml2.DOMDocument.6.0")
   oXmlDoc:async := .F.
   oXmlDoc:validateOnParse := .F.
   oXmlDoc:resolveExternals = .F.

   oXmlDoc:loadXML( cString_XML )  // Usar variable con contenido XML

   oSchema := CreateObject("Msxml2.DOMDocument.6.0")
   oSchema:async := .F.
   oSchema:loadXML( cString_XSD )

   oSchemaCache := CreateObject("Msxml2.XMLSchemaCache.6.0")
   oSchemaCache:add( "", oSchema )

   oXmlDoc:schemas := oSchemaCache

   oParseError := oXmlDoc:validate()

   if !empty( oParseError:errorCode )
      cMensaje := "ERROR! Failed to validate Reason:"+ cStr( oParseError:reason ) +;
                   " Error code: " + Alltrim( Cstr( oParseError:errorCode ) ) +;
                   " Line: " + Alltrim( Cstr(  oParseError:line ) ) +;
                   " Character: " + Alltrim( Cstr(  oParseError:linepos ) ) +;
                   " Source: " + cStr( oParseError:srcText )
      llError := .T.
   else
      lOk := .t.
   endif 
  
   oParseError := NIL
   oSchemaCache := NIL
   oSchema := NIL
   oXmlDoc := NIL

   hb_gcall( .F. )

return cMensaje


KOTLIN. Property , esa cosa que no es un field.

KOTLIN. Property , esa cosa que no es un field. Haciendo una pausa en la documentación, me pongo a experimental el crear / pasar mi...