Estou com um problema de não conseguir liberar memória após dar um release em um formulário com objeto TBrowse dentro.
Ao fechar o Form, sigo essa ordem:
Código: Selecionar todos
oBrw:Destroy() // Destruo o Objeto Tbrowse
DoMethod(cForm,cControl,"Release") // Apago o controle TBrowse
DoMethod(cForm,"Release") // Apago o Formulario criado
Form_Main.SetFocus() // Volto para o principal
Fiz um código teste abaixo, que a cada clicada no botão cria um novo formulário com um objeto TBrowse de 500.000 elementos com nome diferente e ao dar ESC "deveria liberar a memória" mas não está acontecendo...
Se alguém puder me dar uma luz eu agradeço!
Código: Selecionar todos
#include "minigui.ch"
#include "TSBrowse.ch"
PROCEDURE MAIN
Public aHeaders:={"Ordem","Nome_cli","Data","Marcado","Endereco","REG_"}
Public MemoriaInicial:=Alltrim(str(Memory(0)))
DEFINE WINDOW Form_Main;
TITLE "Janela prncipal" MAIN ;
ON GOTFOCUS Atualiza_botao()
@ 175,620 button btn01 caption "Gerar TBrowse - (Memoria Inicial = "+MemoriaInicial +")" Width 480 Height 50 action CreateTBrowse(Memory(0))
END WINDOW
ON KEY ESCAPE of Form_Main ACTION Form_Main.Release
ACTIVATE WINDOW Form_Main
RETURN
//---------------------------------------------------------
FUNCTION CreateTBrowse(nMemoria)
//---------------------------------------------------------
Local F ,ARQ_TEMP:=ARQ_TEMPORARIO()
Local cForm:="FORM_"+ALLTRIM(SUBST(ARQ_TEMP,3,10))
Local oBrw:="oBrw_"+ALLTRIM(SUBST(ARQ_TEMP,3,10))
Private aLista:={}
WAIT WINDOW "Adicionando elementos em aLista{}. Aguarde..." NOWAIT
FOR F := 1 TO 500000
AAdd( aLista, { F, Hb_RandomInt(99) , RandStr( 10 ), Date() - F, if( F % 2 == 0, TRUE, FALSE ), RandStr( 10 ), F*10 } )
NEXT
WAIT CLEAR
DECLARE WINDOW &(cForm)
DEFINE WINDOW &cForm width 600 height 480 TITLE "--- >>> DE UM DUPLO CLICK EM QUALQUER CELULA " ;
ON INIT Atualiza_Botao();
ON RELEASE Atualiza_Botao()
@ 15, 20 LABEL Lbl_Memoria FontColor RED WIDTH 450 HEIGHT 23 ;
VALUE "Memoria Antes de criar o TBrowse = "+Alltrim(str(nMemoria)+" Apos = ")
END WINDOW
DEFINE TBROWSE &oBrw OBJ &(oBrw) ;
AT 45, 2 ;
OF &cForm ;
WIDTH 590 ;
HEIGHT 470;
ON DBLCLICK ( Atualiza_Botao() , PrimeiraFuncao(cForm, &(oBrw), oBrw ) ); // ( Formulario , Objeto Tbrowse , Controle TBrowse )
ON CHANGE Atualiza_Botao();
HEADERS aHeaders ;
GRID
END TBROWSE
ON KEY ESCAPE OF &cForm ACTION FechaForm( cForm, &(oBrw), oBrw ) // ( Formulario , Objeto Tbrowse , Controle TBrowse )
&oBrw:SetArray( aLista, .T. )
&oBrw:Cargo:=aLista
SetProperty(cForm,"Lbl_Memoria","Value",GetProperty(cForm,"Lbl_Memoria","Value")+Alltrim(Str(memory(0))))
ACTIVATE WINDOW &cForm
RETURN oBrw
//---------------------------------------------------------
//---------------------------------------------------------
Function Atualiza_Botao()
//---------------------------------------------------------
SetProperty("Form_Main","btn01","caption","Gerar TBrowse ( Memoria Inicial = "+MemoriaINicial+" Memoria Atual = "+alltrim(str(memory(0)))+" )")
Return NIL
//---------------------------------------------------------
//---------------------------------------------------------
FUNCTION PrimeiraFuncao(cForm, oBrw, cControl) // ( Formulario , Objeto Tbrowse , Controle TBrowse )
//---------------------------------------------------------
Local cQtdElementos,aNewArray01, m1, m2, nLinha, nColuna
m1=alltrim(str(memory(0))) // Antes de atribuir a matriz aLista (que esta em oBrw:cargo) para a aNewArray01
aNewArray01=oBrw:cargo
m2=alltrim(str(memory(0))) // Apos criar a aNewArray01 com o valor de oBrw:cargo
cQtdElementos=Len(aNewArray01)
nLinha=oBrw:nAt
nColuna=oBrw:nCell
// Valor=Alltrim(Hb_ValToStr(GetProperty(cForm,cControl,"value")))
Valor=Hb_ValToStr(aNewArray01[nLinha][nColuna])
msgbox("DENTRO da PrimeiraFuncao()"+Hb_Eol()+ Hb_Eol()+;
"Array inicial aLista com 1000000 elementos atribuida => 'oBrw:cargo:=aLista'"+ Hb_Eol()+ Hb_Eol()+;
"Memoria antes de 'aNewArray01=oBrw:cargo' = "+ M1 + Hb_Eol()+;
"Quantidade de elementos de aNewArray01 = "+alltrim(str(cQtdElementos))+Hb_Eol()+;
"Memoria apos 'aNewArray01=oBrw:cargo' = "+ M2 + Hb_Eol()+;
"Celula clicada: Linha="+alltrim(str(nLinha))+" Coluna="+alltrim(str(nColuna))+ " Valor="+Valor )
SegundaMensagem(cForm, oBrw, cControl, m1, m2)
Return NIL
//---------------------------------------------------------
//---------------------------------------------------------
Function SegundaMensagem(cForm, oBrw, cControl, m1, m2)
//---------------------------------------------------------
Local cQtdElementos,aNewArray02, m3, m4, nLinha, nColuna
m3=alltrim(str(memory(0))) // Antes de atribuir a matriz aLista (que esta em oBrw:cargo) para a aNewArray02
aNewArray02=oBrw:cargo
m4=alltrim(str(memory(0))) // Apos criar a aNewArray02 com o valor de oBrw:cargo
cQtdElementos=Len(aNewArray02)
nLinha=oBrw:nAt
nColuna=oBrw:nCell
// Valor=Alltrim(Hb_ValToStr(GetProperty(cForm,cControl,"value")))
Valor=Hb_ValToStr(aNewArray02[nLinha][nColuna])
msgbox("DENTRO da SegundaFuncao:"+Hb_Eol()+ Hb_Eol()+;
"Memoria antes de 'aNewArray02=oBrw:cargo' = "+ m3 + Hb_Eol()+;
"Na PrimeiraFuncao era ="+M1 + Hb_Eol()+;
"Quantidade de elementos de aNewArray02 = "+alltrim(str(cQtdElementos))+Hb_Eol()+;
"Memoria apos 'aNewArray02=oBrw:cargo' = "+ M4 + Hb_Eol()+;
"Na PrimeiraFuncao era ="+M2 + Hb_Eol()+;
"Celula clicada: Linha="+alltrim(str(nLinha))+" Coluna="+alltrim(str(nColuna))+ " Valor="+Valor )
Return Nil
//---------------------------------------------------------
//---------------------------------------------------------
FUNCTION FechaForm(cForm, oBrw, cControl ) // ( Formulario , Objeto Tbrowse , Controle TBrowse )
//---------------------------------------------------------
m1=alltrim(str(memory(0)))
oBrw:Destroy()
m2=alltrim(str(memory(0)))
DoMethod(cForm,cControl,"Release")
msgbox("Memoria antes do oBrw:Destroy()="+m1+ Hb_Eol()+;
"Memoria apos o oBrw:Destroy()="+m2)
DoMethod(cForm,"Release")
Form_Main.SetFocus()
Return NIL
//---------------------------------------------------------
//---------------------------------------------------------
FUNCTION RandStr( nLen )
//---------------------------------------------------------
LOCAL cSet := "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM"
LOCAL cPass := ""
LOCAL i
FOR i := 1 TO nLen
cPass += SubStr( cSet, Random( 52 ), 1 )
NEXT
RETURN cPass
//-----------------------------------------------------------
//-----------------------------------------------------------
FUNCTION Arq_Temporario() // Gera nome de arquivo temporario
//-----------------------------------------------------------
RETURN "Y_"+ALLTRIM(RIGHT(NETNAME(),2))+ ALLTRIM( STR(INT(SECOND())) )
//-----------------------------------------------------------

