Page 1 of 1

Memory Leak - Activity objects not disposed in SmppSession.cs

Posted: Fri Nov 28, 2025 2:52 pm
by ggsa
Hi alt,

We discovered a memory leak in our production environment. Memory grows from ~2GB to 3.6GB over one week and never releases.

Environment:
- Inetlab.SMPP version: 2.9.35
- .NET 8
- Linux

Memory profiler shows DiagNode<ActivityEvent> objects accumulating: see image1.jpeg

Memory growth over time: see image2.jpeg

Root Cause Analysis:

Found issue in SmppSession.cs - Activity objects not disposed for throttled requests.

Line 960 - throttled path:
_ = SendResponseAndDelayedRequests(resp, null, activity, _cancellationTokenSource.Token);

Activity is created at line 933 but SendResponseAndDelayedRequests never disposes it. Only HandleReceivedRequest disposes activity at line 718, but throttled requests bypass this method.

Can you please review and confirm?

Thank you.

Re: Memory Leak - Activity objects not disposed in SmppSession.cs

Posted: Sat Nov 29, 2025 7:22 am
by ggsa
Update: Possible root cause for our memory leak case - "Activity Theft" in SmppConnection

After deeper look into dotMemory, seems we found the cause.

Profiler Data:
- Activity objects: 49
- DiagNode: 5,158,820 (thousands events per Activity!)
- SmppConnection: 765
- SmppSession: 765

Retention path:
DiagNode<ActivityEvent> → Activity → ExecutionContext
→ AsyncStateMachineBox<SmppConnection+<Transferring>d__63>
→ _transferTask → SmppConnection

Potential bug:

SmppConnection constructor (line 182):
_transferTask = Transferring();

This captures current ExecutionContext. If Activity.Current has value at this moment (e.g., during connection recovery triggered while processing deliver_sm), the Activity might get "stolen" by Transferring() task.

Since Transferring() runs for entire connection lifetime, all subsequent PDU operations call Activity.Current?.AddEvent() (line 487) and add events to this captured Activity.

We have many bindings on this node. Some providers are unstable ("bad actors") and connection recovery is normal situation. When recovery happens during active deliver_sm/submit_sm processing, new SmppConnection captures the Activity from that context.

Result: 49 "contaminated" connections accumulated 5+ million events over one week.

Can you confirm this analysis?