Foros del Web » Programación para mayores de 30 ;) » .NET »

Liberar memoria??

Estas en el tema de Liberar memoria?? en el foro de .NET en Foros del Web. Hola amigos, tengo un problema con mi aplicación ya que va saturando el rendimiento del pc progresivamente, hasta llegar al 100%. (Administrador de tareas > ...
  #1 (permalink)  
Antiguo 25/01/2007, 05:11
Avatar de SuperPinwi  
Fecha de Ingreso: septiembre-2005
Mensajes: 317
Antigüedad: 18 años, 7 meses
Puntos: 1
Exclamación Liberar memoria??

Hola amigos,

tengo un problema con mi aplicación ya que va saturando el rendimiento del pc progresivamente, hasta llegar al 100%. (Administrador de tareas > Rendimiento > Uso de CPU) Creo que el problema radica en que no libera correctamente memoria y así cada vez va a acumulando más y más objetos, yo vengo de java y ahí se liberaba sola con el garbage collector, pero... es igual con vb .net? qué puedo hacer para resolverlo?

gracias amigos!!!
  #2 (permalink)  
Antiguo 25/01/2007, 05:14
Avatar de SuperPinwi  
Fecha de Ingreso: septiembre-2005
Mensajes: 317
Antigüedad: 18 años, 7 meses
Puntos: 1
Re: Liberar memoria??

por cierto, antes de escribir el mensaje he buscado por internet y encontré esta página

http://gdev.wordpress.com/2005/11/30...ia-con-vb-net/

lo he probado y no me da el resultado esperado
  #3 (permalink)  
Antiguo 25/01/2007, 05:51
Avatar de freegirl
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: Catalonia
Mensajes: 4.334
Antigüedad: 20 años, 7 meses
Puntos: 156
Re: Liberar memoria??

pues cuando he leído tu primer post, justamente te iba a poner este ejemplo de liberar la memoria a través de la API.

La verdad que yo lo uso así y hasta la fecha no tengo queja. Aunque los más puristas del .NET me regañaron un poco porque me dicen que no es lo más correcto. Pero oye, a mi es lo que me funciona más.

En .NET también hay el GC. Él se encarga de limpiar....tarde o temprano.

A parte de esto, también es recomendable limpiar manualmente cuando ya no utilizas un objeto. No esperes a que te lo limpie. ´O sea, cerrar los objetos, igualar a nothing o null, llamar a 'dispose', etc. según sea el objeto, claro.

Personalmente, yo utilizo la API y limpio manualemnte (libero recursos) cuando ya no los utilizo, aunque el GC pase la escoba (desde mi punto de vista no es suficiente).

Es un tema interesante esto de liberación de recurosos, por lo cual si alguien puede aportar info....

Saludos!
  #4 (permalink)  
Antiguo 25/01/2007, 06:46
Avatar de .seb  
Fecha de Ingreso: marzo-2006
Ubicación: Uruguay
Mensajes: 493
Antigüedad: 18 años, 1 mes
Puntos: 1
Re: Liberar memoria??

Yo recomiendo que el GC se encargue de todo... personalmente lo que me estaba pasando a mi era que me quedaban conexiones abiertas a la base de datos, y dado que el tiempo de collect era demasiado alto para los tiempos de mi aplicación esto se veía en la performance de la applicación.

De todas formas yo recomiendo dejar al GC que se encargue o en su defecto invocarlo a que haga el collect.
Código:
GC.Collect
Te paso dos articulos que te pueden interesar
http://msdn.microsoft.com/msdnmag/issues/1100/gci/
http://msdn.microsoft.com/msdnmag/issues/1200/GCI2/
__________________
saludos
seba
http://sgomez.blogspot.com
  #5 (permalink)  
Antiguo 25/01/2007, 09:36
Avatar de SuperPinwi  
Fecha de Ingreso: septiembre-2005
Mensajes: 317
Antigüedad: 18 años, 7 meses
Puntos: 1
Re: Liberar memoria??

Muchísimas gracias a los dos!!! he probado lo de gc.collect y también a igualar a nothing adaptadores y otros objetos y me sigue pasando. Se os ocurre alguna otra solución?

el uso de cpu varía según momentos en una serie de este estilo: 3%, 5%, 20%, 3%, 10%, 50%, 3%. 10%, 100% . El pico (100%) tan sólo dura unos pocos segundos, pero en las primeras ejecuciones no se alcanza, si no que va ocurriendo cuando la aplicación ya lleva unos 3 ó 4 minutos funcionando y de ahí en adelante ya siempre se alcanza. Supongo que es importante añadir que hay un método que se ejecuta continuamente a menos que se pulse un botón. Si sirve de ayuda puedo poner el código.

Gracias por vuestra ayuda!!!
  #6 (permalink)  
Antiguo 25/01/2007, 09:46
Avatar de freegirl
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: Catalonia
Mensajes: 4.334
Antigüedad: 20 años, 7 meses
Puntos: 156
Re: Liberar memoria??

la función que maneja la API para liberar recursos, la llamas cada x tiempo? Otra cosilla, a los 4 minutos cuando llega al 100% de CPU ya no baja?

pon el código, si puedes. Así lo vemos mejor.

saludos!
  #7 (permalink)  
Antiguo 25/01/2007, 09:59
Avatar de SuperPinwi  
Fecha de Ingreso: septiembre-2005
Mensajes: 317
Antigüedad: 18 años, 7 meses
Puntos: 1
Re: Liberar memoria??

la función que libera recursos la llamo al final de los 3 métodos que tengo que se repiten continuamente. cuando la CPU llega al 100%, pasa seguidamente un segundo a 3%, después otro al 20% o así más o menos y vuelve al 100% de nuevo. Además me sale, además de la típica línea verde que indica el historial de uso de CPU, otra línea roja en paralelo q no sé porqué sale.

Código:
Public Shared Sub EjecutaLeeBD2()
                While (banderaIniciar = True)
            Try
                'Se abre la conexión de la base de datos
                ObjCleeBD2.Open()
                'Se escogen los registros de la base de datos que se desean
                objAdapter2 = New OleDbDataAdapter("SELECT * FROM Propiedades ORDER BY ID", ObjCleeBD2)
                transaccion2 = ObjCleeBD2.BeginTransaction
                'Se asocia la conexión con el objeto acciones
                objAcciones.Transaction = transaccion2
                objAcciones.Connection = ObjCleeBD2
                objAdapter2.selectcommand.transaction = transaccion2
                'Se almacena la base de datos en el dataTable
                objAdapter2.Fill(dtBD2)
                'Se almacena en n el número de filas de la base de datos
                n = dtBD2.Rows.Count
                transaccion2.Commit()
            Catch ex As Exception
                transaccion2.Rollback()
            Finally
                'Cierra la conexión de la base de datos
                ObjCleeBD2.Close()
            End Try
            actualizaBD1()
            ClearMemory()
            objAdapter2.dispose()
            objAdapter2 = Nothing
            GC.Collect()
        End While
    End Sub

Public Shared Sub actualizaBD1()        
        ReadWriteLock.AcquireWriterLock(System.Threading.Timeout.Infinite)
        If File.Exists(ruta) Then
            Try
                ObjCactualizaBD1.Open()
                transaccion = ObjCactualizaBD1.BeginTransaction()
                objAdaptador2 = New OleDbDataAdapter("SELECT * FROM Propiedades ORDER BY ID", ObjCactualizaBD1)
                objAdaptador2.SelectCommand.Transaction = transaccion
                objAcciones1.Connection = ObjCactualizaBD1
                objAcciones1.Transaction = transaccion
                OleDbUpdateCommand1.Connection = ObjCactualizaBD1
                OleDbUpdateCommand1.Transaction = transaccion
                dtBD1 = New DataTable
                objAdaptador2.Fill(dtBD1)
                n = dtBD1.Rows.Count
                n2 = dtBD2.Rows.Count
                If n = 0 Then
                    MessageBox.Show("No se ha encontrado ningún registro que coincida con la selección", "Aviso")
                Else
                    While fila < n2
                        For Each dr In dtBD1.Rows
                            sID = dr("ID")
                            sDescripcion = dtBD2.Rows(fila)("descripcion").ToString
                            sValor = dtBD2.Rows(fila)("valor").ToString
                            sDescripcion = Chr(34) & sDescripcion & Chr(34)
                            sValor = Chr(34) & sValor & Chr(34)
                            OleDbUpdateCommand1.CommandText = "UPDATE Propiedades SET descripcion = " & sDescripcion & " WHERE ID = " & sID
                            OleDbUpdateCommand1.ExecuteNonQuery()
                            OleDbUpdateCommand1.CommandText = "UPDATE Propiedades SET valor = " & sValor & " WHERE ID = " & sID
                            OleDbUpdateCommand1.ExecuteNonQuery()
                            fila = fila + 1
                        Next
                    End While
                End If
                transaccion.Commit()
            Catch ex As Exception
                transaccion.Rollback()
                MessageBox.Show(Err.Description, "Aviso")
            Finally
                ObjCactualizaBD1.Close()
                ReadWriteLock.ReleaseWriterLock()
            End Try
            ClearMemory()
            objAdaptador2.Dispose()
            objAdaptador2 = Nothing
            dtBD1.Dispose()
            dtBD1 = Nothing
            EjecutaHiloBD()
            ThreadActualizaBD.sleep(6000)
            GC.Collect()
        Else
            MessageBox.Show("No hay una base de datos cargada en este momento, por favor cargue una y vuelva a intentarlo", "Aviso")
        End If
    End Sub


Public Shared Sub EjecutaHiloBD()
                Try
            'Se abre la conexión de la base de datos
            objConn.Open()
            'Se escogen los registros de la base de datos que se desean
            objAdapter = New OleDbDataAdapter("SELECT * FROM Propiedades ORDER BY ID", objConn)
            transaccion3 = objConn.BeginTransaction
            objAcciones.Transaction = transaccion3
            objAdapter.selectcommand.transaction = transaccion3
            'Se almacena la base de datos en el dataTable
            objAdapter.Fill(dt)
            'Se almacena en n el número de filas de la base de datos
            n = dt.Rows.Count
            'Se asocia la conexión con el objeto acciones
            objAcciones.Connection = objConn
            If n = 0 Then
                MessageBox.Show("No se ha encontrado ningún registro que coincida con la selección")
            Else
                'Recorre las filas en el dataTable y las va asignando a las etiquetas
                'del formulario principal para que se muestren
                For fila = 0 To n - 1
                    'Asignar a las variables el contenido del registro
                    sValor = dt.Rows(fila)("valor").ToString
                    sDescripcion = dt.Rows(fila)("descripcion").ToString
                    sVisibilidadLabel = dt.Rows(fila)("visibilidadlabel").ToString
                    sVisibilidadTA = dt.Rows(fila)("visibilidadta").ToString
                    sID = dt.Rows(fila)("ID").ToString
                    'Muestra u oculta los campos según cual sea su valor en la base de datos
                    If sVisibilidadLabel = True Then
                        etiquetas(i).Text = sDescripcion
                        etiquetas(i).Visible() = True
                    Else
                        etiquetas(i).Visible() = False
                    End If
                    If sVisibilidadTA = True Then
                        camposTexto(i).Text = sValor
                        camposTexto(i).Visible() = True
                        'Hacer que los campos que en la base de datos tengan el valor
                        'visible a false, se oculten en el formulario                    
                    Else
                        camposTexto(i).Visible() = False
                    End If
                    i = i + 1
                Next
            End If
            transaccion3.Commit()
        Catch ex As Exception
            MessageBox.Show(Err.Description & Err.Source, "Información del sistema")
            transaccion3.Rollback()
        Finally
            'Cierra la conexión de la base de datos
            objConn.Close()
        End Try
        'Limpiar la memoria
        ClearMemory()
        'Ponemos a nulos los objetos para que los recoja el garbage collector
        Dim bucle As Integer
        objAdapter.dispose()
        objAdapter = Nothing
        GC.Collect()
    End Sub
  #8 (permalink)  
Antiguo 25/01/2007, 10:04
Avatar de SuperPinwi  
Fecha de Ingreso: septiembre-2005
Mensajes: 317
Antigüedad: 18 años, 7 meses
Puntos: 1
Re: Liberar memoria??

bueno q antes no me cabía más jejeje estos 3 métodos lo q hacen es:

1 - lee una base de datos y la almacena en un datatable (dtBD2)
2 - actualiza OTRA base de datos con los datos que había en el datatable
3 - muestra por pantalla el contenido de la base de datos del punto 2 en forma de etiquetas y campos de texto

mi aplicación original sólo constaba del punto 3 y no daba ningún problema... variaba de 2% a 3% el uso de CPU aún estando varias horas activa, así que no entiendo porqué ahora hace esto.

Muchas gracias por el interés y la ayuda!!
  #9 (permalink)  
Antiguo 25/01/2007, 11:35
Avatar de RootK
Moderador
 
Fecha de Ingreso: febrero-2002
Ubicación: México D.F
Mensajes: 8.004
Antigüedad: 22 años, 2 meses
Puntos: 50
Re: Liberar memoria??

Cita:
Iniciado por .seb
De todas formas yo recomiendo dejar al GC que se encargue o en su defecto invocarlo a que haga el collect.
Solo comentario, una cosa es limpiar los objetos manualmente pero a que costo??? usar el GC en algun casos conviene pero el estarlo invocando a cada rato baja performance y además provocas que siempre los objetos se estén creando constantemente y no aprovechas el creado.

En fin, solo es un comentario, es bueno usar dispose, el gc, etc pero también hay que saber lo que hacen y cuando usarlos para saber que tanto nos puede pegar en el performance.

Salu2
__________________
Nadie roba nada ya que en la vida todo se paga . . .

Exentrit - Soluciones SharePoint & Net
  #10 (permalink)  
Antiguo 25/01/2007, 11:53
Avatar de freegirl
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: Catalonia
Mensajes: 4.334
Antigüedad: 20 años, 7 meses
Puntos: 156
Re: Liberar memoria??

Hola

tiene muchas filas y muchos datos el datatable? Según veo ejecutas la función de limpiar memoria después del bucle.Si tienes cientos de registros, estaría bien de llamarla aunque no hayas salido del bucle. O bien en este caso, puedes llamarlo cada minuto, por ejemplo, a través de un timer.

Porque cuanto tiempo está trabajando en cada procedimiento?

Yo probaría (para probar que no quede jeje) de llamarlo cada x tiempo corto, a ver si notas algo. PEro bueno, tampoco es bueno abusar de éste..

saludos!
  #11 (permalink)  
Antiguo 25/01/2007, 12:36
foo
 
Fecha de Ingreso: febrero-2006
Mensajes: 278
Antigüedad: 18 años, 2 meses
Puntos: 0
Re: Liberar memoria??

yo intentaría hacer esa replicación a nivel de base de datos, puesto que en la solución que escogiste se consumen muchos recursos (memoria, tráfico de red, etc)
  #12 (permalink)  
Antiguo 26/01/2007, 00:28
Avatar de SuperPinwi  
Fecha de Ingreso: septiembre-2005
Mensajes: 317
Antigüedad: 18 años, 7 meses
Puntos: 1
Re: Liberar memoria??

hola de nuevo y muchas gracias por vuestra ayuda siempre!! he encontrado el problema, una de las variables se duplicaba sin motivo en cada ejecución, (la q controlaba la salida del bucle de la actualización de la base de datos).
En vez de n2 = DTBD2.rows.count, pongo n2=20 (el número de filas que tiene la base de datos de la q cojo los datos para actualizar) y lo hace perfectamente ya.

De nuevo muchas gracias por vuestro interés y ayuda!!!

Os deseo un estupendo fin de semana
  #13 (permalink)  
Antiguo 26/01/2007, 04:26
Avatar de freegirl
Colaborador
 
Fecha de Ingreso: octubre-2003
Ubicación: Catalonia
Mensajes: 4.334
Antigüedad: 20 años, 7 meses
Puntos: 156
Re: Liberar memoria??

Me alegro superpinwi que lo hayas solucionado. :)

Buen finde!

saludos
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 18:26.