Asunto: Re: Liberando memoria con Java y Orbacus
Fecha: Tue Feb 8 12:14:06 2000
De: Diego Sevilla Ruiz <dsevilla@ditec.um.es>
Hola, Juan:
"Juan A. Botia Blaya" wrote:
> Hola; a ver si alguien me echa una mano.
> Estoy programando con Java, y Orbacus 3.2.1.
> Mi escenario es el siguiente: tengo un servidor de datos, que ofrece tuplas de
> datos, en los cuales el dato correspondiente a cada columna puede
> ser un String o un entero. El
> servidor puede tener varias decenas de miles de esas tuplas, ya creadas en
> forma de objetos tupla_impl, y a disposicion de los clientes.
>
El hecho de que tengas ya creados todos esos objetos hace que el servidor no sea
escalable. Quizá deberías utilizar algún ORB Java que soporte el POA, y no el BOA
como el ORBacus (por ejemplo el JavaORB) que permite tener muchos objetos creados
sin servidor (servant) asociado, con lo cual no se gasta memoria innecesaria en
el servidor. Por ejemplo, puedes implementar un ServantLocator para crear en cada
llamada los objetos requeridos y eliminarlos después. O un ServantActivator para
mantener un conjunto de servidores "activos" que puedes activar y desactivar,
posiblemente utilizando un pool (una caché de objetos activos).
>
> Un cliente, en un momento dado puede necesitar todas esas tuplas, asi que las
> va pidiendo, de una en una, con un servicio Tuple get_next_tuple() que ofrece
> el servidor.
>
> He venido observando que la gestion de memoria en el servidor no es la
> correcta ya que cada 100 llamadas a ese metodo hago
>
> System.out.println("Memoria libre:" + Runtime.getRuntime().freeMemory());
>
> en el servidor, y la memoria disponible va bajando.
>
Bien, esto puede ser por dos razones:
1) que tus métodos no estén bien implementados y causen que se vaya generando
memoria que no se puede liberar (no es que desconfíe, pero es una posibilidad)
2) Que Java no actualice la recolección de basura de forma tan frecuente como tu
requieres. Puedes invocarla explícitamente utilizando el método (gc) creo, aunque
no recuerdo bien dónde está. (¿En System? ¿En Runtime? No me gusta Java ;-)
>
> Hasta ahi todo normal. Sin embargo, esa
> memoria que se ha consumido al hacer disponibles el servidor los objetos al
> cliente, deberia liberarse cuando el cliente finaliza su ejecucion, pero no
> ocurre asi.
>
La gestión de memoria en aplicaciones CORBA se realiza distribuida, es decir,
cada ORB en cada máquina realiza la suya propia. Lo que quiero decir es que
cuando una aplicación termina y deja de utilizar los objetos que residen en el
servidor, no se produce ninguna especie de señal hacia el servidor que le indique
que ese objeto ya no se está utilizando por el cliente. El conteo de referencias
(y por lo tanto, la recolección de basura) siempre se realiza de forma local. En
los clientes con los "stubs", y en los servidores con los "servants".
Resumiendo, lo que se me ocurre es lo siguiente (listado por orden de
preferencia)
1. Utiliza el POA. Al principio es un poco duro, aunque después sólo son
ventajas. Con esto tienes varias opciones:
a) implementar un servant locator y generar y liberar un objeto en sus métodos
preinvoke y postinvoke, respectivamente
b) utilizar un servant activator y, o bien dejar la gestión de los servidores al
POA (utilizando el Active Object Map), o bien llevar tu una especie de caché y
activar y desactivar los objetos cuando los necesites (todo esto son políticas
que puedes elegir en el POA)
c) Utilizar un default servant en el que sólo tienes un "servant" para todos los
objetos y se retornan distintas referencias para el mismo. Todas las peticiones a
los objetos "Tuple" las sirve el mismo servant y accede a la base de datos para
obtener el dato específico para la tupla específica.
2. Utiliza algún método "destroy" que indique cuándo un cliente ya no utiliza un
objeto. En el servidor puedes implementarlo liberando la memoria que ese objeto
consume. Incluso con el BOA (y utilizando un modelo con Threads) puedes llamar a
BOA::deactivate_impl. Y resulta mucho más sencillo con el POA.
El tema no es sencillo. Puedes encontrar más información en el proyecto fin de
carrera de Javier Ros en el que diseñamos el principio de un sistema de caché
para objetos de bases de datos utilizando el POA. Además, el capítulo 11 del
libro de Henning y Vinoski "Advanced CORBA programming with C++" se dedica
ampliamente a este tema. Aunque su principal visión es para C++, el capítulo
también se puede aplicar a Java.
Espero que esto te ayude.
Saludos.
diego.
>
> ¿Alguna idea?
>
> Muchas gracias.
> --
> ******************************************
> Juan A. Botia Blaya. Universidad de Murcia
> Facultad de Informatica.
> Departamento de Informatica, Inteligencia
> Artificial y Electronica.
> Phone +34 968 367343 Fax +34 968 364151
> e-mail: juanbot@fcu.um.es
> ******************************************
--
Diego Sevilla Ruiz -- http://www.ditec.um.es/~dsevilla/
Departamento de Ingeniería y Tecnología de Computadores
Facultad de Informática. Universidad de Murcia
Campus de Espinardo - 30080 Murcia (SPAIN)
Tel.: +34-968-367570
E-mail: dsevilla@ditec.um.es
$_="\\l/) (>". "_'\n<";@@= /.|\n/g;$_=
"\@". "\007f". "DDq". "DD5". "\204".
"\@". "DT4CE". "D54E". "DD". "\244".
"\021". "dBDTC". "\010DD". "\200\$FD\024".
"GDAG". "DAGDT". "CqI";$c =0;$p =5;for$q
(/./g) {$q= ord$q; for(a, b){$z[$c]
=$@[$p+=($q&15) -4];$q>>=4;$c+=33 ;$c>98 &&($c-=98);}};print@z;