DESCARGAS
FOROS
CHAT
NOTICIAS
REVIEWS
ENLACES
FAQ




    Menu Principal

· Inicio
· Enviar noticia
· Enviar eventos
· Miembros
· Estadísticas
· Buscar

· Administración


    Syndication

RSS Noticias
RSS Foros
RSS Downloads
RSS Reviews
RSS Eventos


    eXactas::Staff

 Bienvenido Invitado
Únete a nosotros!



El registro es completamente gratuito y podrás acceder a todas las partes de la web

 Crear una cuenta



 Login:
Usuario:


Contraseña:









Administradores
No Conectado  l0kit0  
No Conectado  cristian  
No Conectado  lucho  
No Conectado  janus  
No Conectado  chgvisual  
No Conectado  Ecthelyon  




Colaboradores
No hay Colaboradores conectados



Miembros:  Conectados
Miembros:  Miembros: 0
Invitados:  Invitados: 5
Total:  Total: 5



  Miembros Online
No hay miembros conectados


    eXactas::Misiones

eXactas::Misiones


    eXactas::Links

Afiliate a nuestra web



    Últimas descargas

 Programación de juegos para móviles con J2ME. (170)
 Programación de videojuegos con SDL para Windows y Linux. (161)
 Concrete Mathematics 2nd. ed. - NOT-OCR (.PDF) (318)


    Últimos links

· PlanetMath
· Clasificados Buenos Aires
· Muchos exámenes de ALPI y resultados


    eXactas::Citas


Oh, esos pobres pícaros que están en las grandes ciudades de a política mundial, hombres jovenes, dotados, torturados por la ambición, que consideran su deber decir su palabra acerca de todos los sucesos -!y siempre sucede algo!

-- Friedrich Nietzsche


    Anti-Spammers

[SPAM poison]



Foros de eXactas.org
No estás conectado





< Tema Anterior   Siguiente Tema > Orden ascendenteOrden descendente  
Autor: Tema: Manejo de memoria en Java
duilio
Moderador





Mensajes: 118
Registrado: 5/6/2004
Estado: Desconectado

  enviado el 27/11/2005 a las 00:04
Un tiempo atrás un compañero de LCC me comentó que en su lugar de trabajo, donde tienen algunos servidores corriendo aplicaciones Java, debían reiniciar éstos todas las noches, pues iban aumentando crecientemente su uso de la memoria, ralentizando el sistema hasta un nivel que los volvía poco usables.

En aquel momento imaginé que la causa se encontraría en algunos programas nativos (no-Java) invocados mediante JNI de una manera incorrecta, con lo cual la solución pasaría por programar correctamente estos wrappers.

Sin embargo un programa Java puro también puede malgastar memoria, como se verá a continuación.

Una aparición común de este fenómeno se da cuando se mantiene una colección de ciertos datos asociados a objetos transitorios mediante un mapeo (HashMap). Por ejemplo, un servidor que escucha en un puerto y quiere mapear cada socket creado al abrir una conexión con un determinado usuario, para facilitar procesamientos posteriores:

code:

import java.util.*;
import java.net.*;

class User {
private String name;

public User(String name) { this.name = name; }
}


class SocketManager {
private Map<Socket,User> m = new HashMap<Socket,User>();

public void setUser(Socket s, User u) {
m.put(s, u);
}
public User getUser(Socket s) {
return m.get(s);
}
public void removeUser(Socket s) {
m.remove(s);
}
}

public class Leaky1
{
public static void main (String[] args)
{
ServerSocket serverSocket;
Socket clientSocket;
SocketManager socketManager = new SocketManager();
String userName;
int userId = 1;

try {
serverSocket = new ServerSocket(1025);
while (true) {
clientSocket = serverSocket.accept();
userName = "Testa" + userId;
System.out.println ("New user " + userName);
socketManager.setUser(clientSocket, new User(userName));
// here you will do something useful, probably launching
// a thread for doing the job
clientSocket.close();
userId++;
}
}
catch (Exception e) {
System.exit(1);
}
}
}



Aquí el servidor escucha en el puerto 1025 en todas las interfaces locales. El ejemplo es un poco irreal pues se crea un usuario nuevo cada vez que se abre una conexión, en un sistema con validación, por ejemplo, la lista de usuarios estará precargada, y he allí el punto fundamental (el tiempo de vida de los User).

Si bien el garbage collector debería limpiar los sucesivos clientSocket devueltos por accept() (ya que al retornar accept() un nuevo Socket, sobreescribe el anterior, perdiendo la referencia), esto no sucede así, pues el socket sigue referenciado en el mapeo. Sin embargo el programa ya no utilizará dicho socket, y aunque intentara hacerlo no podría, pues no tiene una referencia a él.

Hay que notar que el garbage collector no comete ningún error: no recoge los objetos clientSocket pues aún no ha terminado su tiempo de vida (que es el tiempo de todo el programa!), aunque sí es cierto que desde el punto de vista lógico del programa, los clientSocket cuyas referencias se van perdiendo, han terminado su vida útil. Moraleja: (vida de un objeto) == (vida útil de un objeto) es algo que hay que verificar, no necesariamente vale siempre.

En el programa anterior, lo que quisiéramos es que una vez cerrado el Socket cliente y perdida su referencia, su memoria estuviera lista para ser reutilizada. Esto se puede lograr usando una WeakHashMap en lugar de la HashMap, un mapeo construído con referencias débiles. Una referencia débil permite referenciar un objeto, pero sin garantías de que éste no será recogido por el GC. Es decir que antes de utilizar el objeto mediante la referencia débil, se deberá chequear siempre que la misma no sea null, algo engorroso, pero es una molestia que se puede minimizar con un buen diseño, y que será mejor que tener que reiniciar la aplicación regularmente.

Utilizando una WeakHashMap en el programa anterior, todos los objetos serán recolectados luego de terminada su vida útil. Por supuesto otra solución, de hecho la primera que se le ocurre a alguien acostumbrado a programar gestionando la memoria explícitamente, es utilizar SocketManager.remove(clientSocket) en el momento oportuno. Sin embargo esto puede ser no trivial en una aplicación real (en una escenario fuertemente concurrente), y además el ejemplo pretende mostrar lo siguiente: que aún cuando se esté programando en un entorno con memoria gestionada, se deberán conocer los límites y la forma en que se lleva a cabo dicha gestión, ya que el GC por sí solo no puede garantizar completamente una utilización correcta de la memoria.


Saludos,
Duilio.


[Editado el 27/11/2005 por duilio]

 



cristian
Administrador




Mensajes: 114
Registrado: 10/4/2004
Estado: Desconectado

  enviado el 1/12/2005 a las 00:24
Muy interesante, un caso patológico para pizarrón. Pero no será que el garbage collector detecta una referencia a un "objeto tan inutil" que no vale la pena gastar cpu ni siquiera para borrarlo?.

 

____________________
Cristian Rosa

 



 



Académico--------------------   > Novedades   > Ciencias Exactas, Ingeniería y Agrimensura          > ACMLA          > Computación Cuántica   > Ciencia Política y Relaciones Internacionales   > Ciencias Médicas   > Ciencias Bioquímicas y Farmacéuticas   > Arquitectura, Planeamiento y Diseño   > Derecho   > Odontología   > Ciencias Agrarias   > Ciencias Veterinarias   > Ciencias Económicas y Estadística          > Universidad Austral - Encuentros          > Universidad Austral - Examenes          > Universidad Austral - Cursado          > Universidad Austral - El ágora   > Psicología   > Humanidades y Artes   > Comunicacion Social   > Politécnico Superior   > Superior de Comercio General--------------------   > Discusión General   > eXactas   > Arte y Cultura          > Música          > Literatura          > Cine y Teatro   > Computación   > Software libre   > eXactas::Proyectos
Powered by XForum 1.81.1 by Trollix Software



Proyecto eXactas iniciado en abril de 2002 por los estudiantes de la F.C.E.I.A. (U.N.R.).
Abierto a todas las comunidades estudiantiles del planeta, persiguiendo la formacion interdisciplinaria.
Debian Powered CHGHOST | Hosting Provider CHGVISUAL | Branding Programs
Se ve mejor a 1024x768
contacto: webmaster@exactas.org