none
Syste.OutOfMemoryException RRS feed

  • Pregunta

  • Hola Sres buenas tardes.

    Sucede que tengo un odometro que incrementa cada 100 milisegundos y funciona perfectamente.

    El punto es que despues de ciertas horas el programa se cierra solo y es por que se desborda la memoria al aprecer, pues en el registro de eventos me dice que se generó la excepccion system.outofmemory, leyendo encontré que cada generacion de un objeto o evento ocupa un espacio en memoria.

    El punto es que no he ecnontrado como manejar eso.

    el codigo que se ejecuta cada 100 milisegundos es el siguiente:

    El codigo lo llamo desde un evento tick de un control timer que se genera cada 100 milisegundos:

      Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
            Me.SetValue_ContadorProgresivo()
        End Sub
    
    
    Private Sub SetValue_ContadorProgresivo()
            Try
                If (Me.ContadorLabelX.InvokeRequired = True) Then
                    Dim Delegado As SetValue_WithoutParameter_Delegate = New SetValue_WithoutParameter_Delegate(AddressOf SetValue_ContadorProgresivo)
                    Me.ContadorLabelX.Invoke(Delegado, New Object() {})
                Else
                    '********************************************************************************************************************
                    If (Me.TipoTransaccionGlobal.Trim.Equals("Aumento Progresivo")) Then
                        If ((p.P_ValorAcumuladoActual + tp.P_ValorProgresivoMostrandose) >= (Me.ContadorLabelX.Text + (p.P_ValorAcumuladoActual / (DateDiff(DateInterval.Second, Date.Now, DateAdd(DateInterval.Day, 1, Me.tp.P_FechaCreacion)) * 1000)))) Then
                            Me.ContadorLabelX.Text = String.Format("$ {0:N2}", Double.Parse((Me.ContadorLabelX.Text + (p.P_ValorAcumuladoActual / (DateDiff(DateInterval.Second, Date.Now, DateAdd(DateInterval.Day, 1, Me.tp.P_FechaCreacion)) * 1000)))))
                            Try
                                WinSockServer.EnviarDatos(Me.ContadorLabelX.Text) '********************
                            Catch ex As Exception
    
                            End Try
                        Else
                            Me.Set_EstadoTimer(False)
                        End If
                    ElseIf (Me.TipoTransaccionGlobal.Trim.Equals("Pago Premios")) Then
                        If (((p.P_ValorAcumuladoActual) + ((tp.P_ValorProgresivoMostrandose) - Math.Abs(tp.P_ValorTransaccion))) >= (Me.ContadorLabelX.Text + (p.P_ValorAcumuladoActual / (DateDiff(DateInterval.Second, Date.Now, DateAdd(DateInterval.Day, 1, Me.tp.P_FechaCreacion)) * 1000)))) Then
                            Me.ContadorLabelX.Text = String.Format("$ {0:N2}", Double.Parse((Me.ContadorLabelX.Text + (p.P_ValorAcumuladoActual / (DateDiff(DateInterval.Second, Date.Now, DateAdd(DateInterval.Day, 1, Me.tp.P_FechaCreacion)) * 1000)))))
                            Try
                                WinSockServer.EnviarDatos(Me.ContadorLabelX.Text) '********************
                            Catch ex As Exception
    
                            End Try
                        Else
                            Me.Set_EstadoTimer(False)
                        End If
                    ElseIf (Me.TipoTransaccionGlobal.Trim.Equals("Inicializar Progresivo")) Then
                        If (((p.P_ValorAcumuladoActual) + (tp.P_ValorTransaccion)) >= (Me.ContadorLabelX.Text + (p.P_ValorAcumuladoActual / (DateDiff(DateInterval.Second, Date.Now, DateAdd(DateInterval.Day, 1, Me.tp.P_FechaCreacion)) * 1000)))) Then
                            Me.ContadorLabelX.Text = String.Format("$ {0:N2}", Double.Parse((Me.ContadorLabelX.Text + (p.P_ValorAcumuladoActual / (DateDiff(DateInterval.Second, Date.Now, DateAdd(DateInterval.Day, 1, Me.tp.P_FechaCreacion)) * 1000)))))
                            Try
                                WinSockServer.EnviarDatos(Me.ContadorLabelX.Text) '********************
                            Catch ex As Exception
    
                            End Try
                        Else
                            Me.Set_EstadoTimer(False)
                        End If
                    ElseIf (Me.TipoTransaccionGlobal.Trim.Equals("Traslado de Fondos")) Then
                        If ((p.P_ValorAcumuladoActual + tp.P_ValorProgresivoMostrandose) >= (Me.ContadorLabelX.Text + (p.P_ValorAcumuladoActual / (DateDiff(DateInterval.Second, Date.Now, DateAdd(DateInterval.Day, 1, Me.tp.P_FechaCreacion)) * 1000)))) Then
                            Me.ContadorLabelX.Text = String.Format("$ {0:N2}", Double.Parse((Me.ContadorLabelX.Text + (p.P_ValorAcumuladoActual / (DateDiff(DateInterval.Second, Date.Now, DateAdd(DateInterval.Day, 1, Me.tp.P_FechaCreacion)) * 1000)))))
                            Try
                                WinSockServer.EnviarDatos(Me.ContadorLabelX.Text) '********************
                            Catch ex As Exception
    
                            End Try
                        Else
                            Me.Set_EstadoTimer(False)
                        End If
                    End If
                End If
            Catch ex As Exception
                MessageBoxEx.Show(ex.Message, "TablePlay", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End Try
        End Sub

    Necesito saber como liberar memoria en tiempo de ejecucion  des us de cada evento sin que se detenga la generación del event tick.

    Agradezco a todos su acostumbrada colaboracion.


    Walberto Tapia SAyas

    martes, 15 de octubre de 2019 22:38

Todas las respuestas

  • Cuando ocurre eso, se dice que tienes una "fuga de memoria" ("memory leak"). Esto quiere decir que en algún sitio del programa hay alguna operación que asigna memoria, y esa memoria nunca se libera.

    Con la parte que es puro código gestionado ("managed code"), en principio no debería ocurrir nunca. Pero si ese código llama a algún objeto externo que no es de .Net, es factible que se produzca en él una fuga de memoria.

    Dentro de tu código hay al menos dos llamadas a código no-gestionado (y puede que más, dependiendo de lo que hagan internamente los objetos a los que llamas). Una es la llamada a WinsockServer. Si hubiera algún error en la programación interna del WinsokServer, o en la forma en la que lo invocas, se podría producir una fuga de memoria que al cabo de muchas llamadas acabaría consumiendo la memoria del sistema.

    El otro sitio está en la llamada a Invoke. Eso inyecta una petición en la cola de mensajes de Windows para que el hilo de la interfaz ejecute el código que hay en la subrutina pasada como argumento. Si eso lo haces cada 100 milisegundos pero la subrutina tarda más de 100 milisegundos en ejecutarse, entonces se irán acumulando poco a poco los mensajes en la cola e irá consumiendo cada vez más memoria.

    • Propuesto como respuesta Pablo Rubio miércoles, 16 de octubre de 2019 14:38
    miércoles, 16 de octubre de 2019 12:19