Liberar memoria ao fechar Formulario com objeto criado

Projeto MiniGui - Biblioteca visual para Harbour/xHarbour

Moderador: Moderadores

Avatar do usuário
carlaoonline
Usuário Nível 3
Usuário Nível 3
Mensagens: 190
Registrado em: 24 Ago 2014 22:38
Localização: Porto Alegre-RS

Liberar memoria ao fechar Formulario com objeto criado

Mensagem por carlaoonline »

Boa tarde!

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
Porém a memória não libera.

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()))  )
//-----------------------------------------------------------

Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Liberar memoria ao fechar Formulario com objeto criado

Mensagem por JoséQuintas »

Apenas chute, não deveria precisar:

Código: Selecionar todos

ACTIVATE WINDOW &cForm
RETURN oBrw
Insira um aList := {} antes do RETURN.

Mas geralmente a lista é copiada pro objeto, pode não ser a lista correta, apesar que array por default é passado por referência.
Tente também aSize( aList, 0 ) // ou 1
Mesmo caso: se é por referência, talvez := não resolva porque pode perder a referência.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
carlaoonline
Usuário Nível 3
Usuário Nível 3
Mensagens: 190
Registrado em: 24 Ago 2014 22:38
Localização: Porto Alegre-RS

Liberar memoria ao fechar Formulario com objeto criado

Mensagem por carlaoonline »

Bom dia!
JoséQuintas escreveu:Insira um aList := {} antes do RETURN.
Seria uma forma de resolver (mesmo achando que ao destruir o objeto e dar Release no Form seria o suficiente)...Mas não funcionou tb.

Zerei o array aLista e limpei o oBrw:cargo, destrui o objeto, apaguei o controle TBrowse e apaguei o Form... a Memória libera um pouco mas muito longe de chegar perto da memória original antes da criação do TBrowse, E a cada CRIAÇÃO e DESTRUIÇÃO total de um novo Form com TBrowse vai ficando memória presa.... alternei a ordem quando possível em algumas vezes mas nada.

PORÉM percebi que após CRIAR e APAGAR vários TBrowses a ponto de ficar quase sem memória (com RELEASE em todos objetos exceto o form principal que só tem um botão), ao abrir um novo TBrowse (que teóricamente não haveria espaço) daí sim ele libera o suficiente para essa nova nova abertura só que ficou mais lento...talvez esteja gravando em disco ou a lentidão é em função de pouca memória mesmo.....


O sistema é um simples cadastro com milhares de clientes para captação de tele marketing, roda em qualquer PC.
O problema é que tem vários PCs velhos com 1 giga de memória...por isso a preocupação com a memória.


Por hora larguei de mão, nunca será aberto um tbrowse de 1 milhão de linhas...mas poderá ao longo do dia serem abertas e fechadas centenas de telas com centenas de registros em cada vez.....vou monitorar a memória e a rapidez do usuário, talvez force o fechamento e abertura do aplicativo caso diminuir muito a memória.

A cada abertura é criado um Form com nome diferente.... não cheguei a testar se abrir um novo Form com um mesmo nome já usado anteriormente acontece a mesma coisa....talvez eu crie uma lista com 5 nomes e limito a quantidade de listagens abertas simultaneamente... dai vou usando sempre os mesmo nomes de Forms se isso resolver.
Avatar do usuário
momente
Usuário Nível 3
Usuário Nível 3
Mensagens: 496
Registrado em: 03 Mar 2005 11:53
Localização: São Carlos-SP
Contato:

Liberar memoria ao fechar Formulario com objeto criado

Mensagem por momente »

Boa tarde!

Vc testou com HB_GCALL(TRUE) ?
Rogerio L. Momenté
Nada é tão perfeito que não possamos melhorar.
Nunca se explique. Seus amigos não precisam e seus inimigos não vão acreditar.
www.looksystem.com.br
Avatar do usuário
carlaoonline
Usuário Nível 3
Usuário Nível 3
Mensagens: 190
Registrado em: 24 Ago 2014 22:38
Localização: Porto Alegre-RS

Liberar memoria ao fechar Formulario com objeto criado

Mensagem por carlaoonline »

Boa tarde!
momente escreveu:Vc testou com HB_GCALL(TRUE) ?
Inclui ele no programinha teste mas tb não rendeu....

Ao gerar aLista com 4.000.000 de elementos (por exemplo) e logo após dar release a criando novamente aLista com Zero elementos, mesmo usando esse comendo, a memória fica poluída, não libera a ponto de ficar como estava antes da criação do array.
Memória fica presa mesmo apagando a variável.
Memória fica presa mesmo apagando a variável.
Postei abaixo o programa teste. Se alguém quiser testar pode colocar ali 1 ou 3 ou 5 milhões de elementos pra ver, a memória sempre fica presa e só libera após sair do programa.

Código: Selecionar todos

#include "minigui.ch"

//---------------------------------------------------------
Function MAIN
//---------------------------------------------------------
Public nMemoriaInicial:=Alltrim(str(Memory(0)))
Public cMensagem:="Memoria Inicial (antes do Form Main) -> "+nMemoriaInicial+" Kb."+Hb_Eol()
Public aLista:={}, lineFeed:=Hb_Eol()  // +Hb_Eol()

DEFINE WINDOW Form_Main;
   TITLE "Form_Main" MAIN WIDTH 850 HEIGHT 360 ;
   ON GOTFOCUS Atualiza_botao() 
   @ 145,20 LABEL Lbl_1 WIDTH 160  HEIGHT 25 SIZE 12 VALUE "Quant. de elementos"
   @ 145, 170 GetBox Get_1 value 1000000 
   @ 135,320 button btn01 caption "Gerar array  -  (Memoria Inicial = "+nMemoriaInicial +")" Width 480 Height 50 action CriaArray()
END WINDOW

ON KEY ESCAPE of Form_Main ACTION Form_Main.Release
ACTIVATE WINDOW Form_Main

RETURN


//---------------------------------------------------------
Function CriaArray()
//---------------------------------------------------------
Local cForm:="FORM_"+ALLTRIM(SUBST(Arq_Temporario(),3,10))
Local F, nVoltas:=3, nMemoria

DECLARE WINDOW &(cForm) 

DEFINE WINDOW &cForm width 720 height 500 Title "cForm = "+cForm;
       ON INIT Atualiza_Botao();
       ON RELEASE Atualiza_Botao()
       @ 15, 20 LABEL Lbl_Memoria FontColor RED WIDTH 820  HEIGHT 480 SIZE 12;
       VALUE cMensagem
END WINDOW

cMensagem:=cMensagem+"Memoria apos criacao do Form_Main e do "+cForm+"  -> "+alltrim(str(memory(0)))+Hb_Eol()

FOR F=1 TO  nVoltas
    Preenche_Array(.T., cForm, nVoltas)   // .T. = Preenche     .F. = Zera ela
    Preenche_Array(.F., cForm, nVoltas)   // .T. = Preenche     .F. = Zera ela
NEXT

&(cForm).Lbl_Memoria.value:=GetProperty(cForm,"Lbl_Memoria","Value")+LineFeed+ ;
            "Antes da execucao de 'hb_gcAll()'   -> Memoria = "+alltrim(str(memory(0)))


DO EVENTS
hb_gcAll()
DO EVENTS
wApi_Sleep(500)       


nMemoria=Memory(0)

&(cForm).Lbl_Memoria.value:=GetProperty(cForm,"Lbl_Memoria","Value")+LineFeed+ ;
            "Apos a execucao de  'hb_gcAll()'   -> Memoria = "+alltrim(str(nMemoria))


&(cForm).Lbl_Memoria.value:=GetProperty(cForm,"Lbl_Memoria","Value")+LineFeed+Hb_Eol()+ ;
            "Diferenca de memoria = "+Alltrim(str(  Val(nMemoriaInicial)-nMemoria )) 

cMensagem="Memoria Inicial (antes do Form Main) -> "+nMemoriaInicial+" Kb."+Hb_Eol()

ON KEY ESCAPE OF &cForm ACTION &(cForm).Release
ACTIVATE WINDOW &cForm
RETURN 
//---------------------------------------------------------


//---------------------------------------------------------
Function Preenche_Array(lPreencher, cForm, nVoltas)
//---------------------------------------------------------
Static nVezes:=1
Local cString:="", nQuantElem:= GetProperty("Form_Main","Get_1","value")

IF lPreencher
   Atualiza_Botao()
   WAIT WINDOW "Adicionando "+transform(nQuantElem, '99 999 999 999')+" elementos em aLista{}. Etapa "+Alltrim(str(nVezes))+"/"+alltrim(str(nVoltas)) NOWAIT
   cString=Str(nVezes)+" - Antes de criar aLista com "+transform(nQuantElem, '99 999 999 999')+" elementos:  Memoria="+alltrim(str(memory(0)))
   cMensagem=cMensagem+LineFeed+cString
   FOR F := 1 TO nQuantElem
       AAdd( aLista, { F, Hb_RandomInt(99) , RandStr( 10 ), Date() - F, if( F % 2 == 0, TRUE, FALSE ), RandStr( 10 ), F*10   } )
   NEXT
   WAIT CLEAR
   cString=Str(nVezes)+" - APOS criar aLista com "+transform(nQuantElem, '99 999 999 999')+" elementos:  Memoria="+alltrim(str(memory(0)))
   cMensagem=cMensagem+LineFeed+cString
 ELSE
   Release aLista
   Public aLista:={}
   cString=Str(nVezes)+" - Apos Release, e nova criacao de 'aLista' com 'Zero' elementos:  Memoria="+alltrim(str(memory(0)))
   cMensagem=cMensagem+LineFeed+cString+Hb_Eol()
   nVezes=IF(nVezes=3,1,nVezes+1)
ENDIF
&(cForm).Lbl_Memoria.value:=cMensagem+Hb_Eol()
Atualiza_Botao()
Return
//---------------------------------------------------------


//---------------------------------------------------------
Function Atualiza_Botao()
//---------------------------------------------------------
SetProperty("Form_Main","btn01","caption","Gerar Array    ( Memoria Inicial = "+nMemoriaInicial+"    Memoria Atual = "+alltrim(str(memory(0)))+" )") 
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()))  )
//-----------------------------------------------------------




Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7928
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

Liberar memoria ao fechar Formulario com objeto criado

Mensagem por Itamar M. Lins Jr. »

Olá!
Isso é BUG ou do BCC ou do xHarbour. Provavelmente do xHarbour.
Primeiro passo é ver uma Minigui com GCC e Harbour para testar e ver se vai dar o mesmo problema.
Parece que essa do link é com Harbour.
https://sourceforge.net/projects/hmgs-minigui/
Olhei é Harbour com BCC, já da para testar, se é bug do xHb.

Saudações,
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Liberar memoria ao fechar Formulario com objeto criado

Mensagem por JoséQuintas »

carlaoonline escreveu:Postei abaixo o programa teste. Se alguém quiser testar
minigui.png
Alguma idéia?
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Liberar memoria ao fechar Formulario com objeto criado

Mensagem por JoséQuintas »

Tem algum equivalente ao getbox pra testar na OOHG ?
Outro componente mais antigo da HMG.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Liberar memoria ao fechar Formulario com objeto criado

Mensagem por JoséQuintas »

test.png
Sei lá se fiz certo no restante, mas bloqueei hb_gcAll()

Código: Selecionar todos

#include "minigui.ch"

MEMVAR cMensagem, aLista, F, nMemoriaInicial, LineFeed

PROCEDURE MAIN

   PUBLIC nMemoriaInicial := Alltrim( Str( Memory(0) ) )
   PUBLIC cMensagem := "Memoria Inicial (antes do Form Main) -> " + nMemoriaInicial + " Kb." + Hb_Eol()
   PUBLIC aLista := {}, lineFeed := Hb_Eol()  // +Hb_Eol()

   DEFINE WINDOW Form_Main ;
         TITLE "Form_Main" MAIN WIDTH 850 HEIGHT 360 ;
         ON GOTFOCUS Atualiza_botao()
      @ 145,20 LABEL Lbl_1 WIDTH 160  HEIGHT 25 SIZE 12 VALUE "Quant. de elementos"
      @ 145, 170 EDITBOX Get_1
      @ 135,320 button btn01 caption "Gerar array  -  (Memoria Inicial = "+nMemoriaInicial +")" Width 480 Height 50 action CriaArray()
   END WINDOW

   ON KEY ESCAPE of Form_Main ACTION Form_Main.Release
   ACTIVATE WINDOW Form_Main

   RETURN

FUNCTION CriaArray()

   LOCAL cForm := "FORM_" + ALLTRIM( SUBSTR( Arq_Temporario(), 3, 10 ) )
   LOCAL F, nVoltas := 3, nMemoria

   DECLARE WINDOW &( cForm )

   DEFINE WINDOW &cForm width 720 height 500 Title "cForm = " + cForm ;
         ON INIT Atualiza_Botao() ;
         ON RELEASE Atualiza_Botao()
      @ 15, 20 LABEL Lbl_Memoria FontColor RED WIDTH 820  HEIGHT 480 SIZE 12 ;
         VALUE cMensagem
   END WINDOW

   cMensagem := cMensagem + "Memoria apos criacao do Form_Main e do " + cForm + "  -> " + ;
      alltrim( Str( memory(0) ) ) + Hb_Eol()

   FOR F = 1 TO  nVoltas
      Preenche_Array( .T., cForm, nVoltas )   // .T. = Preenche     .F. = Zera ela
      Preenche_Array( .F., cForm, nVoltas )   // .T. = Preenche     .F. = Zera ela
   NEXT

   &( cForm ).Lbl_Memoria.value := GetProperty( cForm, "Lbl_Memoria", "Value" ) + LineFeed + ;
      "Antes da execucao de 'hb_gcAll()'   -> Memoria = " + alltrim( Str( memory(0) ) )

   DO EVENTS
   //hb_gcAll()
   //DO EVENTS
   wApi_Sleep(500)

   nMemoria := Memory(0)

   &( cForm ).Lbl_Memoria.value := GetProperty( cForm, "Lbl_Memoria", "Value" ) + LineFeed + ;
      "Apos a execucao de  'hb_gcAll()'   -> Memoria = " + alltrim( Str( nMemoria ) )

   &( cForm ).Lbl_Memoria.value := GetProperty( cForm, "Lbl_Memoria", "Value" ) + LineFeed + Hb_Eol() + ;
      "Diferenca de memoria = " + Alltrim( Str( Val( nMemoriaInicial ) - nMemoria ) )

   cMensagem := "Memoria Inicial (antes do Form Main) -> " + nMemoriaInicial + " Kb." + Hb_Eol()

   ON KEY ESCAPE OF &cForm ACTION &( cForm ).Release
   ACTIVATE WINDOW &cForm

   RETURN Nil

FUNCTION Preenche_Array( lPreencher, cForm, nVoltas )

   STATIC nVezes := 1
   LOCAL cString, nQuantElem := Val( GetProperty( "Form_Main", "Get_1", "value" ) )

   IF lPreencher
      Atualiza_Botao()
      msgbox( "Adicionando " + transform( nQuantElem, '99 999 999 999' ) + ;
         " elementos em aLista{}. Etapa " + Alltrim( Str( nVezes ) ) + "/" + alltrim( Str( nVoltas ) )  )
      cString := Str( nVezes ) + " - Antes de criar aLista com " + transform( nQuantElem, '99 999 999 999' ) + ;
      " elementos:  Memoria=" + alltrim( Str( memory(0) ) )
      cMensagem := cMensagem + LineFeed + cString
      FOR F := 1 TO nQuantElem
         AAdd( aLista, { F, Hb_RandomInt(99) , RandStr( 10 ), Date() - F, if( F % 2 == 0, TRUE, FALSE ), RandStr( 10 ), F * 10   } )
      NEXT
      MsgBox( Str( nVezes ) + " - APOS criar aLista com " + transform( nQuantElem, '99 999 999 999' ) + " elementos:  Memoria=" + alltrim( Str( memory(0) ) ) )
      cMensagem := cMensagem + LineFeed + cString
   ELSE
      RELEASE aLista
      PUBLIC aLista:={}

      cString = Str( nVezes ) + " - Apos Release, e nova criacao de 'aLista' com 'Zero' elementos:  Memoria=" + alltrim( Str( memory(0) ) )
      cMensagem = cMensagem + LineFeed + cString + Hb_Eol()
      nVezes = IF( nVezes = 3, 1, nVezes + 1 )
   ENDIF
   &( cForm ).Lbl_Memoria.value := cMensagem + Hb_Eol()
   Atualiza_Botao()

   RETURN Nil

FUNCTION Atualiza_Botao()

   SetProperty( "Form_Main", "btn01", "caption", "Gerar Array    ( Memoria Inicial = " + nMemoriaInicial + "    Memoria Atual = " + alltrim( Str( memory(0) ) ) + " )" )

   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() ) ) )
Usei Harbour 3.4 + OOHG + mingw 7.3
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Liberar memoria ao fechar Formulario com objeto criado

Mensagem por JoséQuintas »

mem.png
Sei lá... o array tá no espaço?
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7928
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

Liberar memoria ao fechar Formulario com objeto criado

Mensagem por Itamar M. Lins Jr. »

Olá!
Olha ai:

Código: Selecionar todos

MEMORY( HB_MEM_USEDMAX )
o hbmemory.ch

Código: Selecionar todos

/* NOTE: This file is also used by C code. */

#ifndef HB_MEMORY_CH_
#define HB_MEMORY_CH_

/* Parameters for Memory() function */

/* Standard */
#define HB_MEM_CHAR             0   /* Free Variable Space (KB) */
#define HB_MEM_BLOCK            1   /* Largest String (KB) */
#define HB_MEM_RUN              2   /* RUN Memory (KB) */

/* CA-Cl*pper undocumented */
#define HB_MEM_VM               3   /* Virtual Memory (KB) */
#define HB_MEM_EMS              4   /* Free Expanded Memory (KB) (?) */
#define HB_MEM_FM             101   /* Fixed Memory/Heap (KB) (?) */
#define HB_MEM_FMSEGS         102   /* Segments in Fixed Memory/Heap (?) */
#define HB_MEM_SWAP           103   /* Free Swap Memory (KB) */
#define HB_MEM_CONV           104   /* Free Conventional (KB) */
#define HB_MEM_EMSUSED        105   /* Used Expanded Memory (KB) (?) */

/* Harbour extensions */
#define HB_MEM_USED          1001   /* Memory used (bytes) */
#define HB_MEM_USEDMAX       1002   /* Maximum memory used (bytes) */
#define HB_MEM_STACKITEMS    1003   /* Total items on the stack */
#define HB_MEM_STACK         1004   /* Total memory size used by the stack (bytes) */
#define HB_MEM_STACK_TOP     1005   /* Total items currently on the stack */
#define HB_MEM_BLOCKS        1007   /* Total number of memory blocks allocated */
#define HB_MEM_STATISTICS    1008   /* Return non 0 value if FM statistic is enabled */
#define HB_MEM_CANLIMIT      1009   /* Return non 0 value if used memory limit is supported */
#endif /* HB_MEMORY_CH_ */

Saudações,
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Liberar memoria ao fechar Formulario com objeto criado

Mensagem por JoséQuintas »

Sei lá também...
Mas seria interessante testar no XHarbour.

Código: Selecionar todos


PROCEDURE Main

   LOCAL F, aLista := {}

   SetMode(40,100)
   CLS
   ? "Antes do array: " + Ltrim( Str( Memory(0) ) )

   FOR F := 1 TO 1000000
      AAdd( aLista, { F, Hb_RandomInt(99) , hb_RandomInt(99), Date() - F, F % 2 == 0, hb_RandomInt(99), F * 10   } )
   NEXT
   ? "Depois do array: " + Ltrim( Str( Memory(0) ) )
   aLista := {}
   ( aLista )
   ? "Zerando: " + Ltrim( Str( Memory(0) ) )

   Inkey(0)

   RETURN
hb.png
hb.png (4.67 KiB) Exibido 4660 vezes
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Liberar memoria ao fechar Formulario com objeto criado

Mensagem por JoséQuintas »

Aí complicou.... se é esse teste mesmo.
test.png

Código: Selecionar todos



#define MEM_TEST 1002

PROCEDURE Main

   LOCAL F, aLista := {}

   SetMode(40,100)
   CLS
   ? "Antes do array: " + Ltrim( Str( Memory(MEM_TEST) ) )

   FOR F := 1 TO 1000000
      AAdd( aLista, { F, Hb_RandomInt(99) , hb_RandomInt(99), Date() - F, F % 2 == 0, hb_RandomInt(99), F * 10   } )
   NEXT
   ? "Depois do array: " + Ltrim( Str( Memory(MEM_TEST) ) )
   aLista := {}
   ( aLista )
   ? "Zerando: " + Ltrim( Str( Memory(MEM_TEST) ) )

   Inkey(0)

   RETURN
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Liberar memoria ao fechar Formulario com objeto criado

Mensagem por JoséQuintas »

E isso leva a outra coisa.... O MEU PROBLEMA DE ESTOURAR LIMITES.
Uso muito array.
E agora?
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Liberar memoria ao fechar Formulario com objeto criado

Mensagem por JoséQuintas »

Itamar, por favor, teste isso no Harbour 3.2.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Responder