Skip to content

Conversation

@valerionatangelo
Copy link
Contributor

I was able to reproduce the memory leak with a simple program with the following structure:

var tag = new .... ...;
while(true)
{
   await tag.ReadAsync();
   await Task.Delay(...);
}

If the PLC is online and the tag is readable, there is no memory leak. If there are exceptions on ReadAsync() the process slowly increase CPU and memory usage (it may need to keep failing overnight to reach 100% CPU usage in my environment).

I think the handle created by plc_tag_create_ex should be destroyed in InitializeAsync regardless of the outcome of the async initialization. In the current code, if the result of the initialization is not Status.Ok, the handle is not destroyed immediately and _isInitialized is never set to true so that also the Dispose method cannot destroy the handle.

Some notes on my proposed fix:

  • the handle is destroyed immediately both in case of failed initialization (result is not Status.Ok) and in case of timeout; this let the caller use ReadAsync multiple times on the same Tag instance even in case of Exceptions and without explicitly calling InitializeAsync (since this is permitted by the API, this should also work correcly)
  • call to plc_tag_create_ex is moved before timeout using block to make sure that timeout timer starts only if the async operation actually starts and the handle has been created

The new implementation is tested and it seems to properly fix the issue. Please feel free to improve the code and the its style :)

@timyhac
Copy link
Collaborator

timyhac commented Jul 6, 2025

Hi there - apologies for the delay in replying.

This is some great work and I can get behind your analysis of the problem!

Quite a number of changes has been made to the InitializeAsync method over the last few years, and this change may not be the last one - it would be good to add some unit tests to document the intended behaviour. I think its probably okay to release as the new alpha but I would really like some tests before the official 2.0 release.

@timyhac timyhac merged commit 20480eb into libplctag:main Jul 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants