Visual Basic.NET - Liberar memoria proyecto vb.net

 
Vista:
sin imagen de perfil
Val: 2
Ha aumentado su posición en 24 puestos en Visual Basic.NET (en relación al último mes)
Gráfica de Visual Basic.NET

Liberar memoria proyecto vb.net

Publicado por pedri (73 intervenciones) el 15/06/2021 18:45:31
Buenas, estoy haciendo un proyecto con vb.net, ejecutando un """""For Each ETIQUETA As HtmlElement In web.Document.All""""" constante y cuando llevo mas de 2 o 3 horas me salta error de memoria insuficiente, hay algun codigo de poder liberar la memoria del proyecto para que no desborde? gracias.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de Phil Rob
Val: 3.353
Oro
Ha mantenido su posición en Visual Basic.NET (en relación al último mes)
Gráfica de Visual Basic.NET

Liberar memoria proyecto vb.net

Publicado por Phil Rob (1546 intervenciones) el 15/06/2021 21:10:02
Hola,
Quizá debes buscar todas las líneas de codigo que contienen NEW y verificar que para cada NEW existe una instrucción DISPOSE.
A menudo, el problema de memoria viene de falta de DISPOSE. Existen objetos que no tienen Dispose. En estos casos, debe existir otro metodo para limpiar la memoria.
...
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
sin imagen de perfil
Val: 135
Ha aumentado 1 puesto en Visual Basic.NET (en relación al último mes)
Gráfica de Visual Basic.NET

Liberar memoria proyecto vb.net

Publicado por Agustin (39 intervenciones) el 15/06/2021 21:47:11
1 - Mostrá el codigo de adentro del foreach para entender qué allocations tiene.

2 - compilá en x64.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 2
Ha aumentado su posición en 24 puestos en Visual Basic.NET (en relación al último mes)
Gráfica de Visual Basic.NET

Liberar memoria proyecto vb.net

Publicado por pedri (73 intervenciones) el 15/06/2021 21:59:38
ya tengo la solucion.............por si algien le pasa lo mismo.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Private Declare Auto Function SetProcessWorkingSetSize Lib "kernel32.dll" (ByVal procHandle As IntPtr, ByVal min As Int32, ByVal max As Int32) As Boolean
 
Public Sub LiberarRAM()
 
    Try
 
        Dim memoria As Process
        memoria = Process.GetCurrentProcess()
        SetProcessWorkingSetSize(memoria.Handle, -1, -1)
 
    Catch ex As Exception
 
    End Try
 
End Sub
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
-1
Comentar
sin imagen de perfil
Val: 135
Ha aumentado 1 puesto en Visual Basic.NET (en relación al último mes)
Gráfica de Visual Basic.NET

Liberar memoria proyecto vb.net

Publicado por Agustin (39 intervenciones) el 15/06/2021 22:02:04
Es una pésima idea, pero hacé como quieras.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
-1
Comentar
sin imagen de perfil
Val: 230
Ha aumentado su posición en 2 puestos en Visual Basic.NET (en relación al último mes)
Gráfica de Visual Basic.NET

Liberar memoria proyecto vb.net

Publicado por Cesar (79 intervenciones) el 15/06/2021 22:29:36
Ahí no estás liberando memoria.

Para liberar la memoria, como te dijeron, debes hacer dispose de tus objetos, y adicional, llamar al garbace collector.

Esa API que estás llamando, no la conozco, pero parece que lo único que hace, es decirle al programa que use toda la memoria disponible (lo cual, como te dijeron, es una pésima idea).

Si no muestras el código, no se te puede ayudar a optimizarlo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
2
Comentar
sin imagen de perfil
Val: 2
Ha aumentado su posición en 24 puestos en Visual Basic.NET (en relación al último mes)
Gráfica de Visual Basic.NET

Liberar memoria proyecto vb.net

Publicado por pedri (73 intervenciones) el 16/06/2021 02:06:14
Si teneis alguna idea mejor os pongo el codigo al que coge datos de una web, pero la hacer peticiones con un timer de 1 segundo cada vez que hace un refresh al webbroser creado por codigo va aumentado la memoria como dije el codigo que uso es este:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
Dim CONTAR_LINEA As Integer = 0
Dim NOMBRE_1, NOMBRE_2, NOMBRE_3, NOMBRE_4, NOMBRE_5, NOMBRE_6, NOMBRE_7 As String
Dim web As WebBrowser  'Aquí se declara el WebBrowser
 
    Private Sub CARGAR_PAGINA_INICIO()
 
        web = New WebBrowser() ' Se instancia el WebBrower
        web.ScriptErrorsSuppressed = True ' Oculta la ventana de errores si algún script de la página falló (de todas formas no los necesitamos)
 
        web.Navigate(TextBoxURL.Text)
 
        ' Este Handler permite continuar con el proceso una vez que se ha cargado TODA la página (ya que si no ha cargado lanzará un error)
        AddHandler web.DocumentCompleted, New WebBrowserDocumentCompletedEventHandler(AddressOf OBTENER_DATOS)
 
    End Sub
 
    Public Sub OBTENER_DATOS()
 
        Try
 
            For Each ETIQUETA As HtmlElement In web.Document.All
 
                If ETIQUETA.TagName = "TD" And ETIQUETA.GetAttribute("classname").Contains("card_n") Then
 
                    NOMBRE_1 = LTrim(ETIQUETA.InnerText)
 
                ElseIf ETIQUETA.TagName = "SPAN" And ETIQUETA.GetAttribute("classname").Contains("timer") Then
 
                    NOMBRE_2 = LTrim(ETIQUETA.InnerText)
 
                ElseIf ETIQUETA.TagName = "A" And ETIQUETA.GetAttribute("href").Contains("/t/") Then
 
                    NOMBRE_3 = LTrim(ETIQUETA.InnerText)
 
                ElseIf ETIQUETA.TagName = "TD" And ETIQUETA.GetAttribute("classname").Contains("text-center") Then
 
                    NOMBRE_4 = LTrim(ETIQUETA.InnerHtml)
 
                ElseIf ETIQUETA.TagName = "A" And ETIQUETA.GetAttribute("href").Contains("/r/") Then
 
                    NOMBRE_5 = LTrim(ETIQUETA.InnerText)
 
                ElseIf ETIQUETA.TagName = "A" And ETIQUETA.GetAttribute("href").Contains("/t/") Then
 
                    NOMBRE_6 = LTrim(ETIQUETA.InnerText)
 
                ElseIf ETIQUETA.TagName = "TD" And ETIQUETA.GetAttribute("classname").Contains("text-center") Then
 
                    NOMBRE_7 = LTrim(ETIQUETA.InnerText)
 
                    'PONER DATOSS QUE NOS INTERESA
                    DataGridView1.Rows.Add()
 
                    DataGridView1.Rows(CONTAR_LINEA).Cells(1).Value = NOMBRE_1
 
                    DataGridView1.Rows(CONTAR_LINEA).Cells(2).Value = NOMBRE_2
 
                    DataGridView1.Rows(CONTAR_LINEA).Cells(3).Value = NOMBRE_3
 
                    DataGridView1.Rows(CONTAR_LINEA).Cells(4).Value = NOMBRE_4
 
                    DataGridView1.Rows(CONTAR_LINEA).Cells(5).Value = NOMBRE_5
 
                    DataGridView1.Rows(CONTAR_LINEA).Cells(6).Value = NOMBRE_6
 
                    DataGridView1.Rows(CONTAR_LINEA).Cells(7).Value = NOMBRE_7
 
                    CONTAR_LINEA = CONTAR_LINEA + 1
 
                ElseIf ETIQUETA.TagName = "A" And ETIQUETA.GetAttribute("href").Contains("contactus") Then
 
                    'ORDENAR DATA
                    DataGridView1.Sort(DataGridResultados.Columns(2), System.ComponentModel.ListSortDirection.Descending)
 
                    'QUITAR LA SELECCION DEL DATA
                    DataGridView1.ClearSelection()
 
                    Timer1.Start()
 
                    Exit Sub
 
                End If
 
            Next
 
 
        Catch ex As Exception
 
            My.Computer.Audio.Play(sonidoalerta & "Alerta.wav",
            AudioPlayMode.WaitToComplete)
 
        End Try
 
    End Sub
 
    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
 
        'BORRA LA LISTA
        REFRESCAR_LISTA()
 
        web.Refresh()
 
        OBTENER_DATOS()
 
    End Sub
 
    Private Sub REFRESCAR_LISTA()
 
        Try
 
            If DataGridView1.RowCount > 0 Then
 
                web.Refresh()
 
                DataGridView1.Rows.Clear()
 
            End If
 
            Catch ex As Exception
 
            'MsgBox(ex.Message)
 
        End Try
 
    End Sub
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 230
Ha aumentado su posición en 2 puestos en Visual Basic.NET (en relación al último mes)
Gráfica de Visual Basic.NET

Liberar memoria proyecto vb.net

Publicado por Cesar (79 intervenciones) el 16/06/2021 05:44:55
Hola.

O. K., si entendi bien, cargas una pagina en el webbrowser, y lees el HTML de esa pagina, para crear filas en un gridview.

En este caso, yo sustituiria el webbrowser, por un webclient, y emplearia el metodo downloadstring (https://docs.microsoft.com/en-us/dotnet/api/system.net.webclient.downloadstring?view=netframework-4.7.2#System_Net_WebClient_DownloadString_System_String_).

Dicha clase (webclient), es mucho mas ligera el webbrowser, y te evitas llamar al evento DocumentCompleted.

Solo tendrias que llamar al metodo downloadstring, dentro de tu timer, y leer las etiquetas que deseas.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
sin imagen de perfil
Val: 2
Ha aumentado su posición en 24 puestos en Visual Basic.NET (en relación al último mes)
Gráfica de Visual Basic.NET

Liberar memoria proyecto vb.net

Publicado por pedri (73 intervenciones) el 16/06/2021 22:15:44
no estaria mal probarlo si tienes razon pero el ejemplo que me pusistes es de C++ y yo estoy utilizando Vb.net

1
2
3
4
5
6
7
public static void DownloadString(string address)
{
    WebClient client = new WebClient();
    string reply = client.DownloadString(address);
 
    Console.WriteLine(reply);
}

no me funciona ese ejemplo si yo pongo esto:

1
2
3
Dim web As WebClient = New WebClient
 
Dim h As String = web.DownloadString(TextBoxURL.Text)

despues como leeo las ETIQUETA del HTML con el For Each ETIQUETA As HtmlElement In web.Document.All, espero resolver el problema
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Phil Rob
Val: 3.353
Oro
Ha mantenido su posición en Visual Basic.NET (en relación al último mes)
Gráfica de Visual Basic.NET

Liberar memoria proyecto vb.net

Publicado por Phil Rob (1546 intervenciones) el 17/06/2021 08:00:32
Hola,

Conozco poco del trabajo con WebBrowser pero querría testar tu código.
He copiado tu código en un Form con un DataGridView y un Button para arrancar CARGAR_PAGINA_INICIO().
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        CARGAR_PAGINA_INICIO()
    End Sub
 
   '  No he puesto el Timer en el Form pero lo declare aqui.
    Dim WithEvents Timer1 As New Timer
    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Timer1.Interval = 1000
    End Sub
 
    Dim CONTAR_LINEA As Integer = 0
    Dim NOMBRE_1, NOMBRE_2, NOMBRE_3, NOMBRE_4, NOMBRE_5, NOMBRE_6, NOMBRE_7 As String
    Dim web As WebBrowser  'Aquí se declara el WebBrowser
 
    Private Sub CARGAR_PAGINA_INICIO()
 
        web = New WebBrowser() ' Se instancia el WebBrower
        web.ScriptErrorsSuppressed = True ' Oculta la ventana de errores si algún script de la página falló (de todas formas no los necesitamos)
 
        web.Navigate("https://www.google.com") 'TextBoxURL.Text)    ' Que URL utilizar ???
 
        ' Este Handler permite continuar con el proceso una vez que se ha cargado TODA la página (ya que si no ha cargado lanzará un error)
        AddHandler web.DocumentCompleted, New WebBrowserDocumentCompletedEventHandler(AddressOf OBTENER_DATOS)
 
    End Sub
' ... ... ...

Nada se pasa con este programa, no lineas en DataGridView, no errores, ...
Supongo que no es bien mi URL.

Puedes me enviar una URL que puedo utilizar para testar sin hacer indiscreción ?


Muchas gracias...
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar