Утечка памяти

Язык Visual Basic на платформе .NET.

Модераторы: Ramzes, Sebas

admsasha
Начинающий
Начинающий
 
Сообщения: 1
Зарегистрирован: 13.01.2009 (Вт) 7:58

Утечка памяти

Сообщение admsasha » 13.01.2009 (Вт) 8:03

Есть вот такой код


Код: Выделить всё
Imports System.Net
Imports System.Net.Sockets
Imports System.IO
Imports System.Threading

Module Module1
    Private Structure arrstream
        Dim St1 As System.Net.Sockets.NetworkStream
        Dim St2 As System.Net.Sockets.NetworkStream
    End Structure

    Sub Main()

        Console.Write("Server starting... " & vbCrLf)

        Dim Thread = New System.Threading.Thread(AddressOf tListener)
        Thread.Start()

    End Sub

    Private Sub tListener()
        Dim Client As Net.Sockets.TcpClient
        Dim Stream As System.Net.Sockets.NetworkStream
        Dim Stream2 As System.Net.Sockets.NetworkStream
        Dim st As arrstream
        'Dim Server = New TcpClient

        Dim Listener = New TcpListener(Net.IPAddress.Any, 1234)
        Listener.Start()

        While True
            Client = Listener.AcceptTcpClient()
            Try

                Console.Write("new client: " & Client.Client.RemoteEndPoint.ToString & vbCrLf)

                Dim Server = New TcpClient("10.10.1.1", "8888")

                Stream = Client.GetStream()
                Stream2 = Server.GetStream()

                st.St1 = Stream
                st.St2 = Stream2

                Dim Thread = New System.Threading.Thread(AddressOf srv1)
                Thread.Start(st)
                Thread.Join()

                Dim Thread2 = New System.Threading.Thread(AddressOf srv2)
                Thread2.Start(st)
                Thread2.Join()


            Catch ex As Exception
                Console.Write(ex.Message & vbCrLf)
            End Try

        End While
    End Sub

    Private Sub srv1(ByVal st As arrstream)
        Dim byte1(1024) As [Byte] 'Buffer
        Dim message As String
        'Dim st As arrstream
        Dim Stream As System.Net.Sockets.NetworkStream
        Dim Stream2 As System.Net.Sockets.NetworkStream


        Stream = st.St1
        Stream2 = st.St2

        Try
            While True
                message = Stream.Read(byte1, 0, byte1.Length)
                If Not message > 0 Then
                    Stream.Close()
                    Stream2.Close()
                    Exit Sub
                End If
                message = System.Text.Encoding.GetEncoding("windows-1251").GetString(byte1, 0, message)
                Stream2.Write(byte1, 0, message.Length)
            End While
        Catch ex As Exception
            Console.Write(ex.Message & vbCrLf)
        End Try

    End Sub

    Private Sub srv2(ByVal st As arrstream)
        Dim byte1(1024) As [Byte] 'Buffer
        Dim message As String
        Dim Stream As System.Net.Sockets.NetworkStream
        Dim Stream2 As System.Net.Sockets.NetworkStream

        Stream = st.St1
        Stream2 = st.St2

        Try
            While True
                message = Stream2.Read(byte1, 0, byte1.Length)
                If Not message > 0 Then
                    Stream.Close()
                    Stream2.Close()
                    Exit Sub
                End If

                message = System.Text.Encoding.GetEncoding("windows-1251").GetString(byte1, 0, message)
                Stream.Write(byte1, 0, message.Length)

            End While
        Catch ex As Exception
            Console.Write(ex.Message & vbCrLf)
        End Try

    End Sub

End Module




Если коротко, то сервер сервер должен подключать сколько угодно клиентов и всё что идет на порт 1234, пересылать на 10.10.1.1:8888.

Проблемы. При подключении постоянно выделяется дополнительные 24-44 Кб.

И просьба спецам, оптимизировать и указать какие улучшения можно сделать.

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Re: Утечка памяти

Сообщение ANDLL » 13.01.2009 (Вт) 15:31

Чето какойто бестолковый код в плане потоков.
Зачем писать Thread.start() thread.join??
Вобщем дав основных момента
а) коль скоро код выполняется последовательно избавится от создания useless потоков.
б) Использовать using, везде, где получится.

После этого можно будет чтото сказать, иначе...
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Williams
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1280
Зарегистрирован: 06.05.2008 (Вт) 18:35
Откуда: System.Reflection.Williams (увидел себя в зеркале :))

Re: Утечка памяти

Сообщение Williams » 13.01.2009 (Вт) 19:29

Теперь понятно почему раньше VB разработчикам не давали работать с потоками ))
А насчет using это кому как, он создает лишний рельеф, что ухудшает читаемость кода... Я предпочитаю if obj isnot nothing then obj.dispose
И вы думаете, что вас оставят в живых после прочтения этого поста?

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Re: Утечка памяти

Сообщение ANDLL » 13.01.2009 (Вт) 19:37

А насчет using это кому как, он создает лишний рельеф, что ухудшает читаемость кода... Я предпочитаю if obj isnot nothing then obj.dispose
Эээ. Ты о чем?
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Williams
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1280
Зарегистрирован: 06.05.2008 (Вт) 18:35
Откуда: System.Reflection.Williams (увидел себя в зеркале :))

Re: Утечка памяти

Сообщение Williams » 13.01.2009 (Вт) 19:49

ANDLL писал(а):
А насчет using это кому как, он создает лишний рельеф, что ухудшает читаемость кода... Я предпочитаю if obj isnot nothing then obj.dispose
Эээ. Ты о чем?


Ну например

Код: Выделить всё
Using sr As New StreamReader(SourcePath)
   Using sw As New StreamWriter(DestPath)
       sw.Write(sr.ReadToEnd)
   End Using
End Using


vs

Код: Выделить всё
Dim sr As New StreamReader(SourcePath)
Dim sw As New StreamWriter(DestPath)
sw.Write(sr.ReadToEnd)
If sw IsNot Nothing Then sw.Dispose()
If sr IsNot Nothing Then sr.Dispose()


В комплесных участках кода это несколько затрудняет понимание (первый вариант)
Последний раз редактировалось Williams 13.01.2009 (Вт) 19:59, всего редактировалось 1 раз.
И вы думаете, что вас оставят в живых после прочтения этого поста?

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Re: Утечка памяти

Сообщение ANDLL » 13.01.2009 (Вт) 19:54

А второй вариант это не то же, что и первый
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Williams
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1280
Зарегистрирован: 06.05.2008 (Вт) 18:35
Откуда: System.Reflection.Williams (увидел себя в зеркале :))

Re: Утечка памяти

Сообщение Williams » 13.01.2009 (Вт) 19:59

ANDLL писал(а):А второй вариант это не то же, что и первый

Это очередность или что-то еще?
И вы думаете, что вас оставят в живых после прочтения этого поста?

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Re: Утечка памяти

Сообщение ANDLL » 13.01.2009 (Вт) 20:27

using a

end using
это
try

finally
a.dispose
end try
Полагаю понятно что разница существенна и даже более чем?
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Williams
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1280
Зарегистрирован: 06.05.2008 (Вт) 18:35
Откуда: System.Reflection.Williams (увидел себя в зеркале :))

Re: Утечка памяти

Сообщение Williams » 13.01.2009 (Вт) 21:26

ANDLL писал(а):using a

end using
это
try

finally
a.dispose
end try
Полагаю понятно что разница существенна и даже более чем?


а, ты об этом, технически разница есть, да, но едва-ли здесь может быть исключение отличное от NullReferenceException, которое проверяется при помощи IsNot Nothing, причем даже быстрее
И вы думаете, что вас оставят в живых после прочтения этого поста?

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Re: Утечка памяти

Сообщение ANDLL » 13.01.2009 (Вт) 21:27

Ы? По твоему при записи в поток едва ли может быть исключение? Отнюдь. Может быть куча всего, начиная от сетевых таймаутов и заканчивая отказом оборудывания, не говоря уже о таких как ThreadAbortException, которые могут возникнуть всегда. Думать "в этой строчке не может быть исключений" технически не правильно
Последний раз редактировалось ANDLL 13.01.2009 (Вт) 21:29, всего редактировалось 1 раз.
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Williams
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1280
Зарегистрирован: 06.05.2008 (Вт) 18:35
Откуда: System.Reflection.Williams (увидел себя в зеркале :))

Re: Утечка памяти

Сообщение Williams » 13.01.2009 (Вт) 21:29

ANDLL писал(а):Ы? По твоему при записи в поток едва ли может быть исключение? Отнюдь. Есть к примеру ThreadAbortException, и много других которые бывают где угодно. Думать "в этой строчке не может быть исключений" технически не правильно


:shock: я про obj.Dispose
Последний раз редактировалось Williams 13.01.2009 (Вт) 21:42, всего редактировалось 1 раз.
И вы думаете, что вас оставят в живых после прочтения этого поста?

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Re: Утечка памяти

Сообщение ANDLL » 13.01.2009 (Вт) 21:31

А это тут при чем?
Ты может не заметил, но тут никакие исключения не обрабатываются.
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Williams
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1280
Зарегистрирован: 06.05.2008 (Вт) 18:35
Откуда: System.Reflection.Williams (увидел себя в зеркале :))

Re: Утечка памяти

Сообщение Williams » 13.01.2009 (Вт) 21:42

ANDLL писал(а):А это тут при чем?
Ты может не заметил, но тут никакие исключения не обрабатываются.


Вот именно. Тогда причем тут твой пост про сетевые таймауты и отказ оборудования? Если Using все равно от них не спасет, а NullReferenceException на Dispose моего второго фрагмента проверяется при помощи IsNot Nothing? Для того, чтобы поймать остальные исключения, оба блока придется помещать в Try-Catch.
И вы думаете, что вас оставят в живых после прочтения этого поста?

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Re: Утечка памяти

Сообщение ANDLL » 13.01.2009 (Вт) 22:13

Ээ
Ну подумай
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Williams
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1280
Зарегистрирован: 06.05.2008 (Вт) 18:35
Откуда: System.Reflection.Williams (увидел себя в зеркале :))

Re: Утечка памяти

Сообщение Williams » 13.01.2009 (Вт) 22:27

<суммаризация>
Либо ты никогда не применял второй метод на практике, либо мы говорим на разных языках. Суть в том, что второй фрагмент кода, который я привел, отлично заменяет первый при более высокой удобочитаемости - использую его в своих проектах весьма комфортно. Отношения Using и Dispose примерно такие же, как у SyncLock с методами Enter и Exit класса Monitor. Более короткий путь подходит далеко не каждому.
</суммаризация>
Последний раз редактировалось Williams 13.01.2009 (Вт) 22:32, всего редактировалось 2 раз(а).
И вы думаете, что вас оставят в живых после прочтения этого поста?

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Re: Утечка памяти

Сообщение ANDLL » 13.01.2009 (Вт) 22:32

Нет.
Суммаризация - нужно юзать Using, или читать про финализацию и выяснить что же делает try\finally.
уть в том, что второй фрагмент кода, который я привел, отлично заменяет первый при более высокой удобочитаемости

Я не понимаю, до тебя не доходит что куски в viewtopic.php?p=6709572#p6709572 работают по разному в ряде обычных ситуаций?
использую его в своих проектах весьма комфортно
Это не аргумент. Люди конкатенацию в sql-запросах юзают совершенно спокойно, не всем же это советовать
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

Williams
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1280
Зарегистрирован: 06.05.2008 (Вт) 18:35
Откуда: System.Reflection.Williams (увидел себя в зеркале :))

Re: Утечка памяти

Сообщение Williams » 13.01.2009 (Вт) 22:51

Я понимаю что делает блок Try-Finally и отлично осознаю что можно его использовать напрямую. Но! опять же нужно осуществлять проверку
Код: Выделить всё
        Dim sw As StreamReader
        Try
            sw = New StreamReader("C:\\non-existingfile.txt")
        Catch ex As Exception
            'Обработка исключения
        Finally
            If sw IsNot Nothing Then sw.Dispose()
        End Try


Using делает часть работы за нас, но присутствуют негативные факторы


ЗЫ про конкатенацию ты это загнул :)
И вы думаете, что вас оставят в живых после прочтения этого поста?


Вернуться в Visual Basic .NET

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 11

    TopList  
cron