close Warning: Can't synchronize with repository "(default)" (/var/svn/tolp does not appear to be a Subversion repository.). Look in the Trac log for more information.

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 Víctor de Buen Remiro

Status: newaccepted

comment:2 Changed 10 years ago by Víctor de Buen Remiro

(In [6400]) refs #1815

comment:3 Changed 10 years ago by Víctor de Buen Remiro

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

TotSearchesLostBytesLostBytes/Search
50000237158447.43168
2000079052839.5264
100000474316847.43168
200000948633647.43168
30000158105652.7018666666667
150000711475247.43168
3000001502003250.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 Víctor de Buen Remiro

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í.

Note: See TracTickets for help on using tickets.