Opened 10 years ago
Last modified 10 years ago
#1815 accepted defect
Fuga de memoria con ObjectExist
Reported by: | Pedro Gea | Owned by: | Víctor de Buen Remiro |
---|---|---|---|
Priority: | high | Milestone: | Mantainance |
Component: | Kernel | Version: | 3.1 |
Severity: | critical | Keywords: | |
Cc: |
Description
Se observan fugas de memoria al utilizar frecuentemente la función ObjectExist
.
A continuación se incorpora un ejemplo en el que se puede observar el incremento inesperado en el uso de RAM. Si bien la fuga no es enorme (en el ejemplo utilizado se estima de unos 55.5 KB por cada 1000 llamadas) para proyectos de modelación masivos puede suponer la diferencia entre poder realizar el proceso o no.
Set listado = For(1, 1000, Anything (Real i) { Text name = SetSum(For(1, 10, Text (Real j) { Char(Rand(97,122)) })); PutName(name, i) }); Set For(1, 10, Real (Real n) { SetSum(For(1, 100000, Real (Real i) { ObjectExist("Anything", "listado::abcdefgh") })) }); // incremento de unos 55500 KB de RAM Set For(1, 10, Real (Real n) { SetSum(For(1, 100000, Real (Real i) { FindIndexByName(listado, "abcdefgh") })) }); // no se aprecia incremento de RAM
Change History (4)
comment:1 Changed 10 years ago by
Status: | new → accepted |
---|
comment:2 Changed 10 years ago by
comment:3 Changed 10 years ago by
He hecho unas pruebas para medir la pérdida de bytes en función de varias cosas, como el tamaño del conjunto donde se busca, la longitud de los nombres, el número de ciclos de búsqueda y el número de búsquedas en cada ciclo. De lo único que depende la pérdida es del número total de búsquedas, con una media de 49 bytes por llamada a ObjectExist
TotSearches | LostBytes | LostBytes/Search |
50000 | 2371584 | 47.43168 |
20000 | 790528 | 39.5264 |
100000 | 4743168 | 47.43168 |
200000 | 9486336 | 47.43168 |
30000 | 1581056 | 52.7018666666667 |
150000 | 7114752 | 47.43168 |
300000 | 15020032 | 50.0667733333333 |
Se trata de un problema ya conocido que nunca he sido capaz de resolver. Si algún día saco tiempo puedo reintentarlo pero lo veo complicado.
comment:4 Changed 10 years ago by
En cualquier caso, no es buena idea usar esta función de forma masiva pues resulta muchísimo más lenta. Lo ideal es usar FindIndexByName
cuando se trata de ver si un conjunto tiene un elemento, y siempre asegurándose de que el conjunto está indexado por nombre mediante SetIndexByName
o usando el tercer argumento en Set Append(set,[[...]],True)
Tengo una curiosidad al margen del problema ¿ porqué se usa Anything
cuando se sabe que el tipo del objeto es Real
?. El pseudo-tipo Anything
introduce sobrecarga y resta legibilidad por lo que no es conveniente abusar de él. Imagino que en el código original tendría sentido y al aislar el problema ya se ha quedado así.
(In [6400]) refs #1815