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

Milestone: Mantainance
Priority: highhighest
Severity: criticalblocker
Status: newaccepted
Version: 2.0.1

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

(In [3224]) Refs #1018

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

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

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

Resolution: fixed
Status: acceptedclosed

(In [3225]) Fixes #1018
When a syntax error is found but an object is already created, it must be destroyed

Note: See TracTickets for help on using tickets.