【问题标题】:Windows Service HTTPListener Memory IssueWindows 服务 HTTPListener 内存问题
【发布时间】:2011-02-14 04:15:11
【问题描述】:

对于编写任何代码的“最佳实践”等,我完全是新手。 我倾向于只写一个如果它有效,为什么要修复它。

嗯,这种工作方式让我陷入了困境。我正在编写一个简单的 Windows 服务来为单个网页提供服务。 (此服务将合并到另一个项目中,该项目监控一组服务器上的服务和一些文件夹。)

我的问题是,每当收到请求时,每个请求的内存使用量都会增加几 K,并且每次请求都会保持 qoing。

现在我发现通过将 GC.Collect 放入混合中,它会在某个数字处停止,但我确定它不应该以这种方式使用。我想知道我是否遗漏了什么或没有做一些我应该释放内存的事情。

代码如下:

Public Class SimpleWebService : Inherits ServiceBase
    'Set the values for the different event log types.
    Public Const EVENT_ERROR As Integer = 1
    Public Const EVENT_WARNING As Integer = 2
    Public Const EVENT_INFORMATION As Integer = 4
    Public listenerThread As Thread
    Dim HTTPListner As HttpListener
    Dim blnKeepAlive As Boolean = True

    Shared Sub Main()
        Dim ServicesToRun As ServiceBase()
        ServicesToRun = New ServiceBase() {New SimpleWebService()}
        ServiceBase.Run(ServicesToRun)
    End Sub

    Protected Overrides Sub OnStart(ByVal args As String())
        If Not HttpListener.IsSupported Then
            CreateEventLogEntry("Windows XP SP2, Server 2003, or higher is required to " & "use the HttpListener class.")
            Me.Stop()
        End If
        Try
            listenerThread = New Thread(AddressOf ListenForConnections)
            listenerThread.Start()
        Catch ex As Exception
            CreateEventLogEntry(ex.Message)
        End Try
    End Sub

    Protected Overrides Sub OnStop()
        blnKeepAlive = False
    End Sub

    Private Sub CreateEventLogEntry(ByRef strEventContent As String)
        Dim sSource As String
        Dim sLog As String
        sSource = "Service1"
        sLog = "Application"
        If Not EventLog.SourceExists(sSource) Then
            EventLog.CreateEventSource(sSource, sLog)
        End If
        Dim ELog As New EventLog(sLog, ".", sSource)
        ELog.WriteEntry(strEventContent)
    End Sub

    Public Sub ListenForConnections()
        HTTPListner = New HttpListener
        HTTPListner.Prefixes.Add("http://*:1986/")
        HTTPListner.Start()
        Do While blnKeepAlive
            Dim ctx As HttpListenerContext = HTTPListner.GetContext()
            Dim HandlerThread As Thread = New Thread(AddressOf ProcessRequest)
            HandlerThread.Start(ctx)
            HandlerThread = Nothing
        Loop
        HTTPListner.Stop()
    End Sub

    Private Sub ProcessRequest(ByVal ctx As HttpListenerContext)
        Dim sb As StringBuilder = New StringBuilder
        sb.Append("<html><body><h1>Test My Service</h1>")
        sb.Append("</body></html>")
        Dim buffer() As Byte = Encoding.UTF8.GetBytes(sb.ToString)
        ctx.Response.ContentLength64 = buffer.Length
        ctx.Response.OutputStream.Write(buffer, 0, buffer.Length)
        ctx.Response.OutputStream.Close()
        ctx.Response.Close()
        sb = Nothing
        buffer = Nothing
        ctx = Nothing
        'This line seems to keep the mem leak down
        'System.GC.Collect()
    End Sub
End Class

请随意批评和撕开代码,但请善待。我承认在编码方面我不倾向于遵循最佳实践。

【问题讨论】:

    标签: windows vb.net memory service httplistener


    【解决方案1】:

    你是对的,你应该这样做。删除 Collect() 调用并让它运行一周。任何体面的 .NET 书籍都会讨论垃圾收集器的工作原理以及当您将对象设置为 Nothing 时它如何立即释放内存。在您消耗 2 到 8 兆字节之前,它不会启动。这不是泄漏,只是对丰富资源的有效利用。

    您为每个单独的连接使用一个新线程,这非常昂贵并且当您获得大量连接时扩展性非常很差。考虑改用 ThreadPool.QueueUserWorkItem。线程池线程非常便宜,它们的分配和执行由线程池管理器很好地控制。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-26
      • 2012-01-20
      • 1970-01-01
      • 1970-01-01
      • 2010-10-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多