Opened 14 years ago
Closed 14 years ago
#1018 closed defect (fixed)
Memory leak combining operations and methods
Reported by: | Pedro Gea | Owned by: | Víctor de Buen Remiro |
---|---|---|---|
Priority: | highest | Milestone: | Mantainance |
Component: | OOP | Version: | 2.0.1 |
Severity: | blocker | Keywords: | |
Cc: |
Description
En el marco de evitar problemas en el uso de la memoria RAM con TOL se ha encontrado un error un tanto inesperado.
El problema está bastante profundo dentro del código de MMS, así que he intentado extraer o aislar en un pequeño ejemplo de qué se trata, o al menos por donde van los problemas.
En el ejemplo siguiente, los métodos GetValue1
, GetValue2
y GetValue3
no actúan del mismo modo de cara a NObject
. Sólo el segundo se ajusta a lo esperado.
NameBlock parent = [[ Matrix m = Rand(1,1,1,1); Set instancias = [[ NameBlock instancia = [[ Real GetValue(Real void) { 1 } ]] ]]; NameBlock GetInstancia(Real void) { instancias[1] }; Matrix GetValue1(Real void) { NameBlock ins = parent::GetInstancia(?); Anything data = m * ins::GetValue(?) }; Matrix GetValue2(Real void) { NameBlock ins = parent::GetInstancia(?); Real e = ins::GetValue(?); Anything data = m * e }; Matrix GetValue3(Real void) { NameBlock ins = parent::GetInstancia(?); Anything data = m * {Real ins::GetValue(?)} } ]]; Set For(1, 10, Anything (Real i) { WriteLn(""<<NObject); //Matrix parent::GetValue1(?); Matrix parent::GetValue2(?); //Matrix parent::GetValue3(?); Empty});
El primer método sigue el uso habitual en mucha parte del código.
El segundo método es una forma de solucionarlo.
El tercer método se incluye porque esa forma sí sirvió para solucionar el problema en MMS aunque no parece que valga en este ejemplo.
Change History (5)
comment:1 Changed 14 years ago by
Milestone: | → Mantainance |
---|---|
Priority: | high → highest |
Severity: | critical → blocker |
Status: | new → accepted |
Version: | → 2.0.1 |
comment:2 Changed 14 years ago by
comment:3 Changed 14 years ago by
Aunque no viene a cuento del problema si hay una cosa que no hay que hacer
Anything data = m * ins::GetValue(?)
Eso se sabe que es Matrix, porque es el tipo que devuelve la función, asi que se pone Matrix o no se pone nada. Al poner Anything obligas a evaluar con esa gramática que es más lenta pues tiene que hacer más cosas.
Por ejemplo aquí sí tiene sentido tipar aux como Anything porque no se sabe lo que le vendrá
Anything f(Anything arg) { Anything aux = arg*2; aux -1 }; Real a = f(Real Rand(-1,1)); Matrix b = f(Matrix Rand(2,1,-1,1)); Serie c = f(Serie Rand(-1,1,C));
comment:4 Changed 14 years ago by
He encontrado y no tiene nada que ver con nada de lo que habíamos pensado
Se trata del operador * de Matrix, que como segundo argumento admite Matrix o Real
Ese tipo de funciones built-in que en la declaración admiten una lista de tipos son el problema.
Lo que hacen es ir probando los tipos en el orden dado deshabilitando el sistema de errores, y resulta que hay por ahí un sitio donde tras darse un error por tipo indebido en lugar de destruir el objeto simplemente se ponía a NULL. El error no se ve porque está deshabilitado pero se ha dado.
comment:5 Changed 14 years ago by
Resolution: | → fixed |
---|---|
Status: | accepted → closed |
(In [3224]) Refs #1018