Clipper On Line • Ver Tópico - TXml não libera memoria

TXml não libera memoria

Projeto Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

 

TXml não libera memoria

Mensagempor mhackervix » 16 Ago 2018 09:01

Prezados Amigos,

Estou utilizando a Classe TXml para Processar informações de Milhares de XML da forma abaixo:

Local oXml, cFileXml

.....

Do While .....

.......

oXml := TXmlDocument():New()
oXml:Read( MemoRead( cFileXml ))

......

EndDo

O problema é que com o uso do método "NEW " a cada interação do LOOP (doWhile/EndDo) mais memoria vai sendo alocada até o limite do Windows (a Aplicação da erro por falha na alocação de memoria). Caso o "NEW" seja colocado fora do "LOOP" o método "READ" acumula as leituras dos XML (cFileXml) uma sobre a outra, alocando a mesma quantidade de memoria, assim provocando o mesmo erro do Windows.

Alguém saberia um "método" que apagasse o conteúdo de oXml antes do uso do "READ" (para que não acumulasse mais memoria) ou um "método" que liberasse a memoria apos o uso do object oXml (liberando a memoria utilizada por ele) ?

Desde já agradeço a quem puder ajudar.
Mhackervix, Msc.
Avatar de usuário

mhackervix
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 105
Data de registro: 11 Fev 2008 01:06
Cidade/Estado: ES
Curtiu: 1 vez
Mens.Curtidas: 2 vezes

TXml não libera memoria

Mensagempor Kapiaba » 16 Ago 2018 10:21

  cXmlFile:=MemoRead(cXmlFile)

  oXmldoc:=TXmlDocument():New(cXmlFile,HBXML_STYLE_NOESCAPE )
Kapiaba
Colaborador

Colaborador
 
Mensagens: 1765
Data de registro: 07 Dez 2012 15:14
Cidade/Estado: São Paulo
Curtiu: 310 vezes
Mens.Curtidas: 119 vezes

TXml não libera memoria

Mensagempor Kapiaba » 16 Ago 2018 10:23

 oDoc := TXmlDocument():New(cXML, HBXML_STYLE_NOESCAPE)

if oDoc:nError != HBXML_ERROR_NONE

   ? "Erro ao ler o XML dos correios"

endif
Kapiaba
Colaborador

Colaborador
 
Mensagens: 1765
Data de registro: 07 Dez 2012 15:14
Cidade/Estado: São Paulo
Curtiu: 310 vezes
Mens.Curtidas: 119 vezes

TXml não libera memoria

Mensagempor alxsts » 16 Ago 2018 11:54

Olá!

Tente assim:
Local oXml, cFileXml

.....

Do While .....

.......

oXml := TXmlDocument():New()
oXml:Read( MemoRead( cFileXml ))

......

oXml := NIL
hb_gcAll()  // Chamada ao Garbage Collector -> limpa "lixo" da memória

EndDo
[]´s
Alexandre Santos (AlxSts)
alxsts
Colaborador

Colaborador
 
Mensagens: 2943
Data de registro: 12 Ago 2008 15:50
Cidade/Estado: São Paulo-SP-Brasil
Curtiu: 21 vezes
Mens.Curtidas: 248 vezes

TXml não libera memoria

Mensagempor mhackervix » 16 Ago 2018 15:16

Amigo,

Obrigado.

Funcionou perfeitamente.

alxsts escreveu:Olá!

Tente assim:
Local oXml, cFileXml

.....

Do While .....

.......

oXml := TXmlDocument():New()
oXml:Read( MemoRead( cFileXml ))

......

oXml := NIL
hb_gcAll()  // Chamada ao Garbage Collector -> limpa "lixo" da memória

EndDo
Mhackervix, Msc.
Avatar de usuário

mhackervix
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 105
Data de registro: 11 Fev 2008 01:06
Cidade/Estado: ES
Curtiu: 1 vez
Mens.Curtidas: 2 vezes

TXml não libera memoria

Mensagempor alxsts » 16 Ago 2018 17:50

Olá.

Bom que resolveu.

De qualquer forma, isto me parece um bug que deve ser reportado para a equipe do Harbour. Afinal, se eu criar mil instâncias da mesma classe, atribuindo sempre à mesma variável, cada instância deveria vir "limpa" e não com "sujeira" da instânvia anterior...
[]´s
Alexandre Santos (AlxSts)
alxsts
Colaborador

Colaborador
 
Mensagens: 2943
Data de registro: 12 Ago 2008 15:50
Cidade/Estado: São Paulo-SP-Brasil
Curtiu: 21 vezes
Mens.Curtidas: 248 vezes

TXml não libera memoria

Mensagempor mhackervix » 16 Ago 2018 18:10

Como reportar um Bug a equipe Harbour?
Mhackervix, Msc.
Avatar de usuário

mhackervix
Usuário Nível 3

Usuário Nível 3
 
Mensagens: 105
Data de registro: 11 Fev 2008 01:06
Cidade/Estado: ES
Curtiu: 1 vez
Mens.Curtidas: 2 vezes

TXml não libera memoria

Mensagempor Itamar M. Lins Jr. » 16 Ago 2018 21:28

Ola!
Harbour ou xHarbour ?
Qual é sua distribuição ?
Esse é um bug velho do xHarbour...
No Harbour não usamos hb_gcall()
Tá lá para quem quiser ve/ler as mazelas do xHB... /doc/hb-diff.txt

### OBJECT DESTRUCTORS ###
================================
Both Harbour and xHarbour support object destructors and both
compilers uses reference counters and garbage collector to
execute destructors. Anyhow the low-level implementation is
different in the two compilers. In Harbour HVM is reentrant safe
so the implementation of destructors is much simpler. It also
keeps full control about reference counters and detects user
code errors bound with complex items in .prg and C code what
greatly helps to detect problems in user code or 3rd party
libraries and gives protection against internal HVM memory
corruption. In the last years it also helped to located few
very hard to exploit bugs in core code.

In xHarbour there is some basic protection but it was never
fully functional. Sometimes it may cause that internal error
message is generated but in most of cases internal HVM memory
is silently corrupted. A good example which illustrates what
may happen is in Harbour source repository in harbour/tests/destruct.prg
This code can be compiled and executed by Harbour and xHarbour.
But only Harbour version detects user errors generating RTE
and is necessary in all cases to keep internal memory cleaned
protecting against corruption. The xHarbour version behavior
is random because this .prg code corrupts internal HVM memory.
It's possible that it will be executed without any visible
errors or it will generate GPF or internal error. But in all
cases it can be well seen using tools like Valgrind or CodeGuard
that it corrupts internal memory so the results are unpredictable.
I.e. this is part of Valgrind log generated during execution
of above destruct.prg compiled by xHarbour:

==22709== Invalid read of size 2
==22709== at 0x426E235: hb_gcItemRef (garbage.c:646)
==22709== by 0x425EDE5: hb_memvarsIsMemvarRef (memvars.c:2396)
==22709== by 0x426E674: hb_gcCollectAll (garbage.c:847)
==22709== by 0x426E899: HB_FUN_HB_GCALL (garbage.c:1179)
==22709== Address 0x485b096 is 22 bytes inside a block of size 56 free'd
==22709== at 0x4023B7A: free ()
==22709== by 0x42837A9: hb_arrayReleaseBase (arrays.c:1588)
==22709== by 0x428381A: hb_arrayRelease (arrays.c:1602)
==22709== by 0x4256B94: hb_itemClear (fastitem.c:248)
[...]
==22709== Invalid write of size 2
==22709== at 0x426E4C6: hb_gcItemRef (garbage.c:652)
==22709== by 0x425EDE5: hb_memvarsIsMemvarRef (memvars.c:2396)
==22709== by 0x426E674: hb_gcCollectAll (garbage.c:847)
==22709== by 0x426E899: HB_FUN_HB_GCALL (garbage.c:1179)
==22709== Address 0x485b096 is 22 bytes inside a block of size 56 free'd
==22709== at 0x4023B7A: free ()
==22709== by 0x42837A9: hb_arrayReleaseBase (arrays.c:1588)
==22709== by 0x428381A: hb_arrayRelease (arrays.c:1602)
==22709== by 0x4256B94: hb_itemClear (fastitem.c:248)
[...]
==22709== Invalid read of size 4
==22709== at 0x426E223: hb_gcItemRef (garbage.c:603)
==22709== by 0x425EDE5: hb_memvarsIsMemvarRef (memvars.c:2396)
==22709== by 0x426E674: hb_gcCollectAll (garbage.c:847)
==22709== by 0x426E899: HB_FUN_HB_GCALL (garbage.c:1179)
==22709== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==22709== Process terminating with default action of signal 11 (SIGSEGV)
==22709== Access not within mapped region at address 0x0

Harbour executes above code cleanly without any errors:

==28376== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 3 from 1)
==28376== malloc/free: in use at exit: 0 bytes in 0 blocks.
==28376== malloc/free: 6,164 allocs, 6,164 frees, 10,323,064 bytes allocated.
==28376== All heap blocks were freed -- no leaks are possible.

Missing protection and error detection is not only problem for programmers.
It also causes that in xHarbour core code few bad bugs have not been fixed
so far though they exist for years. It also extremely time consuming problem
for core developers when users or 3rd party developers reports problems with
some memory corruption and it's necessary to locate the reason.
I remember how much time I lost for such things working on xHarbour
in the past so later when I moved to Harbour it was one of the main goal
for me to resolve the problem.

In xHarbour there is disabled code which was designed to detect such
problems and it can be enabled by setting HB_ARRAY_USE_COUNTER_OFF macro
but it causes horrible runtime overhead and was never finished to be ready
as production extension. Such solution seems to be dummy way so I do not
believe that it will be ever finished.


Saudações,
Itamar M. Lins Jr.
Avatar de usuário

Itamar M. Lins Jr.
Colaborador

Colaborador
 
Mensagens: 6927
Data de registro: 30 Mai 2007 11:31
Cidade/Estado: Ilheus Bahia
Curtiu: 309 vezes
Mens.Curtidas: 503 vezes

TXml não libera memoria

Mensagempor alxsts » 16 Ago 2018 22:24

Olá!
Itamar M. Lins Jr. escreveu:Tá lá para quem quiser ve/ler as mazelas do xHB... /doc/hb-diff.txt

Grato pela gentileza do esclarecimento. Eu desconhecia isto. Mais um ponto para o Harbour!
Itamar M. Lins Jr. escreveu:Harbour ou xHarbour ?
Qual é sua distribuição ?
Boa pergunta! Vamos aguardar a resposta.
Itamar M. Lins Jr. escreveu:No Harbour não usamos hb_gcall()
Consta no Manual do Harbour e não diz que não deve ser usado...
[]´s
Alexandre Santos (AlxSts)
alxsts
Colaborador

Colaborador
 
Mensagens: 2943
Data de registro: 12 Ago 2008 15:50
Cidade/Estado: São Paulo-SP-Brasil
Curtiu: 21 vezes
Mens.Curtidas: 248 vezes




Retornar para Harbour

Quem está online

Usuários vendo este fórum: Nenhum usuário registrado online e 5 visitantes


Ola Amigo, espero que meu site e forum tem lhe beneficiado, com exemplos e dicas de programacao.
Entao divulgue o link da Doacao abaixo para seus amigos e redes sociais ou faça uma doacao para o site forum...
MUITO OBRIGADO PELA SUA DOACAO!
Faça uma doação para o forum
cron
v
Olá visitante, seja bem-vindo ao Fórum Clipper On Line!
Efetue o seu login ou faça o seu Registro