Título: (SOLUCIONADO) Fuga de memória en una función :( Publicado por: Eleкtro en 4 Agosto 2013, 15:01 pm Tengo una fuga de memória grave en una aplicación, y es debido a una Class de terceros que estoy usando...
Este simple código aloja entre 100-200kb de RAM cada segundo :( Código
Necesito usar un Timer rápido de menos de 50 ms, pero simplemente por curiosidad si aumento el Timer a 1000 ms la ram sigue subiendo sin pausa, aunque sube sólo 8 kb cada segundo. He intentado examinar y corregir la Class pero no encuentro el fallo, esta es la parte de la Class que manipula el code de arriba: Código
Código
Pero la primera condición no se cumple, es decir, solo se manipula esta parte de la función Bind: Código
hWnd_Winamp es un IntPtr waProcess es un Process (el cual he probado a liberarlo pero sigue pasando lo mismo...) waPID es un Integer hWnd_Playlist es un IntPtr hWnd_Equalizer es un IntPtr hWnd_Video es un IntPtr ...y GetWindowThreadProcessId es esta función: Código
y esta la función GetHWND: Código
¿Alguna sugerencia? Gracias... Título: Re: Fuga de memória en una función :( Publicado por: Novlucker en 7 Agosto 2013, 17:17 pm Hay algo que no entiendo y es ... ¿Por que ese necesario buscar cada 50 ms la ventana y el proceso de Winamp? Está claro que es algo muy costoso, ¿no alcanza con obtenerlo una vez?
Saludos Título: Re: Fuga de memória en una función :( Publicado por: Eleкtro en 7 Agosto 2013, 17:29 pm Hay algo que no entiendo y es ... ¿Por que ese necesario buscar cada 50 ms la ventana y el proceso de Winamp? Está claro que es algo muy costoso La intención de repetirlo cada 50 ms es para detectar cuando el Winamp está en modo "Pausa" o en "Detenido", o para detectar si el proceso sigue activo o si ya no se está ejecutando el Winamp, si se te ocurre una forma más eficiente plz dímelo. EDITO: Para que entiendas lo que hago, tengo algo así: Código
PD: ¿Entonces tu tampoco encuentras el problema en el code de arriba? Saludos Título: Re: Fuga de memória en una función :( Publicado por: Novlucker en 7 Agosto 2013, 17:55 pm ¿No hay un evento en esa clase para detectar el cambio de estado?
En cuanto al proceso por ejemplo. Lo obtienes todas las veces y seteas EnableRaisingEvents en true, lo que hay que hacer es obtener el proceso, setear EnableRaisingEvents en true, suscribirse al evento Exited, y dejar de buscar el proceso. Cuando se dispara el evento Exited, entonces volvemos a buscar. Saludos Título: Re: Fuga de memória en una función :( Publicado por: Eleкtro en 7 Agosto 2013, 18:08 pm ¿Por que ese necesario buscar cada 50 ms la ventana y el proceso de Winamp? Está claro que es algo muy costoso Aún así ese trozo de código de la Class genera memoria sin cesar, aunque se use un Timer que tickee cada 10 segundos que llame a la función Bind, la cantidad de memoria en ese caso será minima pero al fin y al cabo incesante, hay algo que está mal en ese code. ¿No hay un evento en esa clase para detectar el cambio de estado? En cuanto al proceso por ejemplo. Lo obtienes todas las veces y seteas EnableRaisingEvents en true, lo que hay que hacer es obtener el proceso, setear EnableRaisingEvents en true, suscribirse al evento Exited, y dejar de buscar el proceso. Cuando se dispara el evento Exited, entonces volvemos a buscar. la Class del Winamp son 2000 o 3000 lineas de código, no me lo he mirado todo, eso es lo próximo que haré y ya te cuento. Título: Re: Fuga de memória en una función :( Publicado por: Novlucker en 7 Agosto 2013, 19:39 pm Pero en principio te puedes fijar si tiene un evento, solo es poner punto en el nombre de instancia de clase y buscar el que tiene un "rayito" :xD
Saludos Título: Re: Fuga de memória en una función :( Publicado por: Eleкtro en 7 Agosto 2013, 19:50 pm Pero en principio te puedes fijar si tiene un evento, solo es poner punto en el nombre de instancia de clase y buscar el que tiene un "rayito" :xD Si pero si el evento fuese privado por cualquier motivo pues no me iba a salir en el intellisense, es que en la class hay muchos "Tests" como cosas de prueba y cosas por mejorar, no está del todo perfeccionado así que tenía que usar el buscador de la IDE para examinar la class a fondo xD.Citar ¿No hay un evento en esa clase para detectar el cambio de estado? No, ninguno, hay que crear el evento o detectar el estado a lo cutre, mediante condiciones (if's).En fín Novlucker he seguido tus indicaciones para lo del proceso: En la class del winamp: Código
En la class de mi form: Código
Se nota mucho el cambio, gracias, aunque como ya digo la función Bind de esa class tiene algún problema así que por mucho que yo intente perfeccionar estas minucias no va a dejar de subir la RAM xD, aunque ahora he conseguido que suba reálmente muy poco a poco, el consumo de ram hace subidas y bajadas que no me gustan nada, pero bueno parece estar equilibrado, sube un poco y al rato como que el GC hace su trabajo, lo libera y vuelve a bajar el consumo, y vuelve a subir, en fin xD. (Todo esto dejando el proceso en "StandBy") Saludos Título: Re: Fuga de memória en una función :( Publicado por: Novlucker en 7 Agosto 2013, 20:31 pm Yo creo que el problema está no en la función, sino en ejecutar esa función constantemente tan rápido. Se crean más datos de los que se alcanzan a liberar.
Te pongo un ejemplo, Código
El código es muy simple, pero si lo ejecutas verás como la RAM va aumentando progresivamente :P Saludos Título: Re: Fuga de memória en una función :( Publicado por: Eleкtro en 7 Agosto 2013, 20:53 pm Yo creo que el problema está no en la función, sino en ejecutar esa función constantemente tan rápido. Se crean más datos de los que se alcanzan a liberar. Lo que dices es muy lógico, es lo primero que se llega a pensar, puede que si que quizás en 50 ms se generen más datos de los que se pueden liberar, pero además de eso estoy seguro de que hay una fuga en esa función, y la prueba definitiva la di al principio, con este code: Código
Símplemente el Test consiste en crear una APP con ese código (y adjuntar la dll de la función Bind claro xD). Repito que si uso un Timer de 10 segundos (o 20, o los que sean) la RAM sigue subiendo progresívamente, solo que se generarán los bytes mucho más lento porque el timer es más lento así que hay que dejar la app un buen rato corriendo para apreciar el aumentado del consumo de RAM, pero en fín yo creo que en 10-20 segundos el GC tiene tiempo de liberar... Saludos! Título: Re: Fuga de memória en una función :( Publicado por: Eleкtro en 8 Agosto 2013, 18:13 pm Bueno creo que puedo dar este tema por solucionado...
me ha costado mucho tiempo corregir cada parte del código de la aplicación que tenían fugas de memória pero al final he estabilizado el consumo y ya no aumenta progresívamente, de los 12 MB no pasa nunca el consumo ahora, ya puedo dejar de colectar manuálmente con el GC y de usar API's para flushear el consumo de memória de la APP xD Gracias por tu tiempo Novlucker. Lo único que me gustaría mejorar sobre el tema de la memória es lo que comento aquí: Tema: Experimento de consumo de memória... ver para creer! (Leído 58 veces) (http://foro.elhacker.net/net/experimento_de_consumo_de_memoria_ver_para_creer-t396464.0.html) Saludos! |