Who's problem - used memory increased w/o decrease

Please post requests related to the sipsorcery library to the GitHub repo https://github.com/sipsorcery/sipsorcery/issues.
Locked
Henry
Posts: 5
Joined: Thu Sep 09, 2010 1:59 am

Who's problem - used memory increased w/o decrease

Post by Henry » Thu Dec 30, 2010 8:51 am

Help needed, I posted one item about use SIP components - viewtopic.php?f=3&t=2790&p=16787&hilit=Henry#p16787. Here's the item following it with same background.

When I use the Sip Sorcery' SIP Components to make simple point 2 point call / answer just like softphone done, the used memory increased when more call made and without decrease even after call GC.Collection. So please point me what's the problem.

Let me explain about the code:

1. I used configuration file to tell what's the two points so that they can connect each other, something like following:

Code: Select all

  <appSettings>
    <add key="Local" value="127.0.0.1:5060"/>
    <add key="Remote" value="127.0.0.1:6060"/>
  </appSettings>
Each item tells the IP Address and port will be used.

2. Prepare the local SIP Transport as following:

Code: Select all

        private void InitialiseSIP()
        {
            // Configure the SIP transport layer.
            m_sipTransport = new SIPTransport(SIPDNSManager.ResolveSIPService, new SIPTransactionEngine());
            m_sipTransport.AddSIPChannel(new SIPUDPChannel(m_sipEp));

            m_sipTransport.SIPTransportRequestReceived += SIPTransportRequestReceived;

            IsReady = true;
        }
m_sipEp is coming from the Local item' setting from configuration file.

3. The SIPTransportRequestReceived used to process coming SIP request, the code for INVITE is as following:

Code: Select all

            // Send Trying when get INVITE to prevent dup coming INVITE
            SIPResponse res = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Trying, null);
            Transport.SendResponse(res);
            Thread.Sleep(200);

            res = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ringing, null);
            Transport.SendResponse(res);
            Thread.Sleep(10);

            UASInviteTransaction uasTransaction = Transport.CreateUASTransaction(sipRequest, remoteEndPoint, localSIPEndPoint, null);
            SIPServerUserAgent uas = new SIPServerUserAgent(Transport, null, null, null, SIPCallDirection.In, null, null, LogTraceMessage, uasTransaction);
            uas.CallCancelled += UASCallCancelled;

            string toTag = CallProperties.CreateNewTag();

            string sdp = CreateSDP(m_sipEp.Address.ToString()).ToString();
            Thread.Sleep(300);

             uas.Answer("application/sdp", sdp, toTag, null, SIPDialogueTransferModesEnum.NotAllowed);

            Thread.Sleep(15000);
            uas.SIPDialogue.Hangup(m_sipTransport, null);
The code is used to show the problem, so hard coded. It responses the coming call with trying, ringing, then accepted, after sleep 15 seconds ended the call.

4 The INVITE coming from call as following:

Code: Select all

                SIPEndPoint proxyEP = new SIPEndPoint(mRemote);
                SIPClientUserAgent uac = new SIPClientUserAgent(m_sipTransport, proxyEP, null, null, LogTraceMessage);
                uac.CallTrying += CallTrying;
                uac.CallRinging += CallRinging;
                uac.CallAnswered += CallAnswered;
                uac.CallFailed += CallFailed;

                SIPCallDescriptor callDescriptor = GetCallDescriptor(info, m_sipEp);
                uac.Call(callDescriptor);
The info include the call information: caller, callee etc.

5. As the response to the BYE request, the 200 OK is sent.

6. For testing, a loop is used to make calls.

For detail please see full code in attachment files - it's the sip wrapper coming from my working project - a console project which can server as both the sip server and sip client. You can copy the build result to another place and modify the configuration file so that two instances can run as a pair, start one as server, start another one as client with an argument as the testing call time such as "siptest 10". Use the Task manage to watch usage of memory, after the sip port is ready, under client one's console input 'r' and enter to start the call testing, you can find that the memory used by both items are increased when process call. Under console input 'END' and enter to end the SIP - GC.Collection is called after that, you can find the number of Handle of both instances decrease in task manage.

Anyone can point me where the problem and how can I make the used memory decrease.

Thanks in advance!

Henry
Attachments
SIPTest.zip
Source Code
(7.42 KiB) Downloaded 168 times

Aaron
Site Admin
Posts: 4652
Joined: Thu Jul 12, 2007 12:13 am

Re: Who's problem - used memory increased w/o decrease

Post by Aaron » Thu Dec 30, 2010 10:45 am

I ran you test 200 times and the physical working set memory on the client test app went from 3.5MB to just under 5MB. In my experience that's perfectly normal. The .Net runtime doesn't free memory in the way a C or C++ program will in that it automatically discards memory from its working pool at the first opportunity. Instead it seems to keep hold of some allocated memory in case it needs it in the future. At a certain threshold it will get more aggressive about memory deallocation so as not to consume up all the system resources. This approach makes sense as memory allocation is probably a relatively expensive operation and it's more efficient to keep hold of existing allocations up to a point.

That's not to say .Net apps or the sipsorcery SIP stack are free of memory leaks. I am aware of a memory leak in the IronRuby processing of the sipsorcery dialplans and spent the best part of a year trying to fix it with no success. Your sample does not use IronRuby so you are not encountering that leak.

I don't think there is a leak in your example but to test a .Net application properly 10 iterations will not usually be sufficient to highlight it. ideally you should be performing 10,00 or even 100,000 iterations. At those levels the .Net runtime won't be able to keep hold of all it's memory allocations without consuming all the available memory and a steady state should be reached.

Henry
Posts: 5
Joined: Thu Sep 09, 2010 1:59 am

Re: Who's problem - used memory increased w/o decrease

Post by Henry » Fri Dec 31, 2010 5:54 am

Thank you, Aaron.

It seems that I'm a little hurry to make this post, because other guy using the SIP wrapper I made based on SIP Sorcery's SIP components to make stress testing - hundreds call per minutes and the memory usage increased quickly, so I made this test project.

I run the testing again and waited for hours, just as you said the memory usage increased not so much and after GC.Collection the memory usage also decreased. So wait is needed.

Thanks again and Happy new year!

Henry

Locked