FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour XBrowse con AddResource > Consumo progresivo de Memoria
Posts: 54
Joined: Sat Dec 10, 2016 08:58 PM
XBrowse con AddResource > Consumo progresivo de Memoria
Posted: Sat Jan 17, 2026 05:14 PM

Hola a todos

Después de mucho tiempo de nuevo acá, en otro intento por modernizar mi software.

Por favor si alguien me puede ayudar con esto:

En XBrowse (muy bueno!!!) incluyo columnas que muestran pequeños bitmaps, usando AddResource, y cuando esas columnas están visibles en el navegador, cada desplazamiento, de cualquier forma, aumenta el consumo de memoria (leído con administrador de tareas de Windows), de modo que si desplazo hacia abajo o hacia arriba el contador sube y sube.

Por otro lado, sin tocar nada, cuando oculto las columnas, el contador de consumo de memoria se congela, no sube sin importar cuanto navegue. Vuelvo a activar las columnas, y el contador vuelve a subir al navegar. Y es similar con 100, 1.000 o 20.000 registros.

Este es un código fuente de ejemplo, que funciona y presenta el problema indicado:

aCabe := { '', 'Aut', 'Seg' }
aData := { 'CLAVE', 'Au', 'Se' }
aPict := { '', '', '' }
aSize := { 150, 30, 30 }

cQry :=  'Select CLAVE, CRAYON1 As Au, CRAYON2 As Se From MOVMAE Limit 2000'
oQry:= oMyCon:Rowset(cQry,.f.)

Define Dialog oDlg Resource 'BROXSDVD' Font oFontGral Title 'Prueba'

Redefine XBrowse oBrw ID 100 Of oDlg Update DataSource oQry Columns aData Headers aCabe ColSizes aSize Pictures aPict 

add column to oBrw at 1    // inserté una columna para ejemplo, pero podría ser una existente...
oBrw:aCols[1]:AddResource( { 'COMUN_SELECC_NO', 'COMUN_SELECC_SI' } )
oBrw:aCols[1]:cHeader         := '>'
oBrw:aCols[1]:cToolTip        := 'Muestra'
oBrw:aCols[1]:nHeadStrAlign   := 2      // (centrado)
oBrw:aCols[1]:nWidth          := 30
oBrw:aCols[1]:cSortOrder      := nil
oBrw:aCols[1]:bLClickHeader   := { || '' }
oBrw:aCols[1]:lBmpStretch     := .f.
oBrw:aCols[1]:lBmpTransparent := .t.
oBrw:aCols[1]:bBmpData        := { || if( ascan( oBrw:aSelected, oBrw:BookMark ) > 0, 1, 2 ) }
oBrw:aCols[1]:bStrData        := { || '' }
oBrw:aCols[1]:bEditValue      := { || '' }
oBrw:aCols[1]:nDataBmpAlign   := 2
oBrw:aCols[1]:cEditPicture    := Nil
oBrw:aCols[1]:blDClickData    := { || MiMsgInfo( 'probando' ) }
oBrw:aCols[1]:bClrStd       := { || { CLR_BRWHT, CLR_BRWHB } }

Activate Dialog oDlg

RETURN Nil

He probado mil cosas y no logro resolverlo.

Además, al salir del navegador, aunque haga release, end(), y asigne nil, aún así la cantidad de memoria consumida hasta el momento permanece (no baja, no libera).

Uso HB MSVSC + FWH 24.04 + MySQL/MariaDB/DBFCDX (64 bits)

Muchas gracias, que tengan un excelente fin de semana.

José Concha Leiva - Chile
"Querer, saber y hacer, es poder"
HB MSVSC + FWH 24.04 + MySQL/MaríaDB/DBFCDX (64 bits)
https://zenitx.com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: XBrowse con AddResource > Consumo progresivo de Memoria
Posted: Mon Jan 19, 2026 05:16 AM

Estimado José,

Lo estamos revisando.

Gracias por tu feedback :idea:

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: XBrowse con AddResource > Consumo progresivo de Memoria
Posted: Mon Jan 19, 2026 06:01 AM

Estimado José,

Al comienzo de tu app llama a:

SetResDebug( .T. )

Añade una opción a tu menú principal desde donde llames a este código:

MENUITEM "Consumo" ACTION ( FErase( "checkres.txt" ), CheckRes(), WinExec( "notepad checkres.txt" ) )

Sin salir de tu app, prueba el consumo de recursos y copia el log que te aparezca en pantalla y dáselo a la IA para que lo analice.

Asi es como estamos intentando localizar el consumo que reportas. Gracias!

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: XBrowse con AddResource > Consumo progresivo de Memoria
Posted: Mon Jan 19, 2026 06:02 AM

He analizado el log de recursos (checkres.txt) que has proporcionado. Este log es la "pistola humeante" (prueba definitiva) de que tienes objetos GDI que no se están destruyendo al cerrar la ventana o finalizar el proceso.

Aquí está el desglose de dónde viene la pérdida y los duplicados:

1. El problema del Pintado (Confirmación de tu sospecha)

Hay una entrada crítica al final del log que confirma que el repintado (scroll o refresh) está dejando basura:

01/19/26 06:55:49: ... BRUSH, 2131760879, TXBROWSE:PAINT(2350)->...

  • Análisis: El método Paint (línea 2350 en tu versión de xbrowse.prg) crea un BRUSH (Pincel) para pintar el fondo o un área específica, y nunca lo destruye.
  • Impacto: Cada vez que el Paint se ejecuta (y se ejecuta cientos de veces al hacer scroll), si esa línea condicional se cumple, se crea un nuevo pincel. Si no hay un DeleteObject() correspondiente para ese pincel específico, la memoria se llena rápidamente.

2. Duplicados en la creación (TXBROWSE:NEW)

Hay tres Bitmaps que se crean al instanciar el Browse (NEW) y quedan vivos. Fíjate en estas líneas:

  1. BMP, 50667437, TXBROWSE:NEW(853)...
  2. BMP, 251994086, TXBROWSE:NEW(854)...
  3. BMP, -217768098, TXBROWSE:NEW(854)...
  • Identificación: Las líneas 853 y 854 del xbrowse.prg original suelen corresponder a la carga de los bitmaps de ordenación (flechas arriba/abajo) en la variable ::aSortBmp.
  • ¿Por qué hay duplicados?
  • La línea 854 aparece dos veces con handles diferentes (251994086 y -217768098).
  • Esto indica que, o bien se han creado dos xBrowses y ninguno se ha destruido, o bien el código de inicialización ha cargado ese recurso dos veces para el mismo browse.
  • Causa de la fuga: Estos bitmaps se guardan en variables internas o en aBitmaps. Si el log los muestra al final, significa que el método Destroy() del XBrowse no se ejecutó o no pudo limpiar estos handles específicos.

3. Fuga en Columnas (TXBRWCOLUMN)

BMP, 788861018, TXBRWCOLUMN:ADJUST(13680)...

  • Durante el ajuste de la columna, se creó un Bitmap (posiblemente para un Checkbox o un botón de filtro) que quedó huérfano.

Conclusión y Solución

El log indica que el objeto TXBrowse (y sus columnas) no está completando su ciclo de destrucción.

  1. Fuga en Paint (Urgente): Revisa la línea 2350 de tu xbrowse.prg. Debería haber un código similar a DEFINE BRUSH ... o CreateSolidBrush. Debes asegurarte de que ese pincel se libere con DeleteObject() o RELEASE BRUSH antes de que termine el método Paint.
  2. Fallo en End/Destroy: Los bitmaps de NEW (853/854) son nativos de la clase. Si aparecen aquí, es porque la ventana contenedora (el TMDIFRAME o TMDICHILD) no envió correctamente el mensaje de destrucción al control XBrowse, o el método Destroy del XBrowse falló antes de llegar a la limpieza de bitmaps.

Prueba recomendada:
Asegúrate de que en tu ventana principal o dialogo, el objeto browse se asigne a una variable local o DATA y sea parte de la lista de controles de la ventana (oWnd:aControls). El mecanismo de FiveWin limpia automáticamente los recursos solo si el control está correctamente enlazado a la ventana que se cierra.

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: XBrowse con AddResource > Consumo progresivo de Memoria
Posted: Mon Jan 19, 2026 06:14 AM

Parece que hay una pérdida de recursos que no está monitorizando FWH

Seguimos investigándolo

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 54
Joined: Sat Dec 10, 2016 08:58 PM
Re: XBrowse con AddResource > Consumo progresivo de Memoria
Posted: Mon Jan 19, 2026 01:06 PM

Hola Antonio

Muchas gracias, haré las pruebas que me indicas.

Quedo atento a cualquier información.

Saludos.

José Concha Leiva - Chile
"Querer, saber y hacer, es poder"
HB MSVSC + FWH 24.04 + MySQL/MaríaDB/DBFCDX (64 bits)
https://zenitx.com
Posts: 1789
Joined: Tue Oct 11, 2005 05:01 PM
Re: XBrowse con AddResource > Consumo progresivo de Memoria
Posted: Thu Jan 22, 2026 01:13 AM

antonio, en esa linea, en el actual xbrowse, existe esto:

      // To enable programmer to change color during runtime
      DeleteObject( ::hBrushRecSel )
      ::hBrushRecSel := CreateColorBrush( ::nRecSelColor )  //aca es la linea 2350

aca se crea un brush, el cual previamente se elimina, pero durante toda la vida de la funcion Paint, no es eliminado.

Salu2

Carlos Vargas

Desde Managua, Nicaragua (CA)
Posts: 1789
Joined: Tue Oct 11, 2005 05:01 PM
Re: XBrowse con AddResource > Consumo progresivo de Memoria
Posted: Thu Jan 22, 2026 01:20 AM
...
EXTEND CLASS TXBROWSE     WITH METHOD SetMyBmpSort
...

FUNCTION SetMyBmpSort()
   LOCAL Self := hb_QSelf()
   LOCAL oBmp, hBmp

   IF ::aSortBmp[ 1, 1 ] != 0
      DeleteObject( ::aSortBmp[ 1, 1 ] )
   ENDIF
   IF ::aSortBmp[ 2, 1 ] != 0
      DeleteObject( ::aSortBmp[ 2, 1 ] )
   ENDIF

   ::aSortBmp := {}

   DEFINE BITMAP oBmp NAME "BMS_ARROWDOWN"
   hBmp := oBmp:hBitmap
   AAdd( ::aSortBmp, { hBmp, 0, nBmpWidth( hBmp ), nBmpHeight( hBmp ), NIL, FALSE } )

   DEFINE BITMAP oBmp NAME "BMS_ARROWUP"
   hBmp := oBmp:hBitmap
   AAdd( ::aSortBmp, { hBmp, 0, nBmpWidth( hBmp ), nBmpHeight( hBmp ), NIL, FALSE } )

RETURN NIL

Este código nos muestra la forma correcta de realizar un cambio en los bitmaps de las flechas de ordenación, si el usuario desea cambiar los que usa fwh por defecto y usar los propios cambiando ::aSortBmp, debe tener el cuidado de borrar los anteriores correctamente, como muestra la función que adjunto.

Salu2

Carlos Vargas

Desde Managua, Nicaragua (CA)
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: XBrowse con AddResource > Consumo progresivo de Memoria
Posted: Thu Jan 22, 2026 05:38 AM
carlos vargas wrote:

antonio, en esa linea, en el actual xbrowse, existe esto:

      // To enable programmer to change color during runtime
      DeleteObject( ::hBrushRecSel )
      ::hBrushRecSel := CreateColorBrush( ::nRecSelColor )  //aca es la linea 2350

aca se crea un brush, el cual previamente se elimina, pero durante toda la vida de la funcion Paint, no es eliminado.

Estimado Carlos,

Probé a comentar esas dos líneas y aún así, se mantiene el consumo de recursos. Debe ser algo más pero aún no lo hemos localizado. No queda registrado en el registro de recursos de FWH.

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 54
Joined: Sat Dec 10, 2016 08:58 PM
Re: XBrowse con AddResource > Consumo progresivo de Memoria
Posted: Thu Jan 29, 2026 01:52 AM

Hola Antonio

¿Hay alguna novedad respecto a esto?

Saludos

José Concha Leiva - Chile
"Querer, saber y hacer, es poder"
HB MSVSC + FWH 24.04 + MySQL/MaríaDB/DBFCDX (64 bits)
https://zenitx.com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: XBrowse con AddResource > Consumo progresivo de Memoria
Posted: Thu Jan 29, 2026 09:55 AM

Hemos localizado la herramienta idónea para localizar el tipo de objeto GDI que no se está liberando:

GDIView
https://www.nirsoft.net/utils/gdi_handles.html

En concreto la versión de 64 bits:
https://www.nirsoft.net/utils/gdiview-x64.zip

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: XBrowse con AddResource > Consumo progresivo de Memoria
Posted: Thu Jan 29, 2026 10:55 AM

Bug detectado en tgdiplus.prg:

METHOD Destroy() CLASS Region

   //  GdiPlusDeletePen( ::hRegion )  incorrecto
   GdiPlusDeleteRegion( ::hRegion ) // correcto

   ::hRegion = nil

return nil

código para GdiPlusDeleteRegion() en gdiplus.cpp:

HB_FUNC( GDIPLUSDELETEREGION )
{
   delete ( ( Region * ) hb_parptr( 1 ) );
}
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: XBrowse con AddResource > Consumo progresivo de Memoria
Posted: Mon Feb 02, 2026 11:56 PM

GDI+ leak solucionado!

Audit gdipfwh.cpp for Memory Leaks Completed the comprehensive audit of gdipfwh.cpp

. Identified and fixed multiple critical memory leaks where GDI+ objects (Graphics, FontFamily, Bitmap, Brush) were allocated with new but not deleted.

Applied fixes to 11 functions including GDIP_RINGGRAD, GDIP_DRAWARROW, GDIP_DRAWTEXT, and image handling functions.

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: XBrowse con AddResource > Consumo progresivo de Memoria
Posted: Tue Feb 03, 2026 12:03 AM

José,

Indicame si necesitas las librerias para Borland o MS, 32 ó 64 bits, y te las enviamos :idea: :D

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 54
Joined: Sat Dec 10, 2016 08:58 PM
Re: XBrowse con AddResource > Consumo progresivo de Memoria
Posted: Tue Feb 03, 2026 03:40 PM

Estimado Antonio

Hola, que buena noticia que se haya resuelto!!

Yo uso Harbour MSVSC 64 bits (Harbour 3.2.0dev) FWH 24.04, 64 bits (04/2024) Pelles C 64 bits, para Windows, v 9.00.9, 2018 MySQL/MariaDB/DBFCDX

Así que entiendo que serían las librerías para MS, 64 bits.

Nota. Aprovecho de preguntar si, con la configuración que uso, podría actualizar VSCode 2022 a VSCode 2026 (enero 2026) sin romper algo de la configuración o del proyecto.

Gracias por todo, quedo atento.

José Concha Leiva - Chile
"Querer, saber y hacer, es poder"
HB MSVSC + FWH 24.04 + MySQL/MaríaDB/DBFCDX (64 bits)
https://zenitx.com