mardi 5 mai 2015

Memory leak in .NET Windows service logging network packets

I am logging packets from the network with a NDIS LWF. The driver sends the packet to a DLL which then passes the data to a .NET service. The service then does some processing on the data and dumps it to a Postgres database. I'm experiencing a memory leak (I think) in the Windows service after what seems to be a random amount of time. When working properly, the average CPU usage for the service is around 3% while the memory is pretty consistent between 15000-20000k. For a yet to be determined reason, the CPU will jump to 25% and stay while the memory will go up to about 95% of total available memory on the system. So a few more implementation details. Within the service, when the DLL calls the .NET service I copy the data over to a byte array within a class object. I then add this object to a ConcurrentQueue and signal an event. Abbreviated code is:

'rawDataIntPtr is an unmanaged BYTE* coming from the C DLL which is then freed once this callback returns

ReDim pkt.data(dataLen)
Marshal.Copy(rawDataIntPtr, pkt.data, 0, dataLen)
gLfq.Enqueue(pkt)
gLfqItemAdded.Set()

A separate thread is used respond to new data and dequeues the data from the queue. As stated above, it does some processing then adds packet information to a Postgres database with a call to ExecuteNonQueryAsync(). Here's the relevant code parts of my consumer thread:

wh(0) = gShutdownEvent
wh(1) = gLfqItemAdded
While (True)
    whRet = WaitHandle.WaitAny(wh)
    If whRet = 0 Then
        Exit While
    End If

    Try
        glfqItemAdded.Reset()
    Catch ex As Exception
        LogError()
    End Try

    While gLfq.TryDequeue(pkt)

        'Do Stuff Here

        query = "INSERT TO DATABASE"
        ExecuteNonQueryWrapperAsync()

        'I've tried the various things to try and clear
        'all references to the byte array and packet object
        'thinking this was my problem
        ReDim pkt.data(0)
        pkt.data = Nothing
        pkt = Nothing
    End While
End While

I've tried SciTech's .NET Memory Profiler 5.0, and it shows, when the CPU and memory spike, that there are an abundance of byte arrays currently allocated which makes sense. But that alone isn't very useful and it's not the easiest tool in the world to understand. I suppose if it was a memory leak though, I'd see a slow increase in memory usage however, that's not the case. So my issue is maybe it is not a memory leak but perhaps a component falling behind in processing which then causes a backlog of data. But I don't understand why it will work fine for a period of time then suddenly just spike and get out of whack. Network usage is pretty consistent as well so I don't believe it has to do with spikes in traffic. If more code is needed or additional details, let me know. Or if my design is messed up, I'd like to hear that too. Thanks.

Aucun commentaire:

Enregistrer un commentaire