Professional OPC
Development Tools

logos

Online Forums

Technical support is provided through Support Forums below. Anybody can view them; you need to Register/Login to our site (see links in upper right corner) in order to Post questions. You do not have to be a licensed user of our product.

Please read Rules for forum posts before reporting your issue or asking a question. OPC Labs team is actively monitoring the forums, and replies as soon as possible. Various technical information can also be found in our Knowledge Base. For your convenience, we have also assembled a Frequently Asked Questions page.

Do not use the Contact page for technical issues.

Memory growth observed with when ReadValue() is executed at a fast rate.

More
02 Dec 2021 16:08 #10418 by support
Hello.

In my test, moving the statement
_EasyUAClientPtr ClientPtr(__uuidof(EasyUAClient));
outside (before) the loop resolves the problem.

Now, having it inside the loop should not be a problem in theory. But, unnecessary creation of EasyUAClient objects is discouraged, because EasyUAClient is relatively "heavy" object in terms of construction cost and resource usage. So, given that it's not recommended practice anyway, would it be OK if the customer tries moving it outside the loop and leave it at that then?

Best regards

Please Log in or Create an account to join the conversation.

More
01 Dec 2021 15:23 #10414 by support
Hello.

QuickOPC/OPC Data Client code runs in .NET. Always. And it always uses .NET memory management. The COM interface sits "on top" of the .NET objects. So, even if the developer is using the COM interfaces of the product, there is still .NET running and doing the memory management for the .NET part.

Now, in your original post, you have not mentioned the crash - you just wrote that the memory gets consumed and then it seems to go back - which appeared harmless.

I will check the code / try to reproduce, and let you know. I noticed that there is sometimes a need to let the .NET garbage collector a chance to run - which is not well documented by Microsoft. We will see. Please give me some time.

Best regards

Please Log in or Create an account to join the conversation.

More
01 Dec 2021 13:56 #10413 by Restrepo
I see, Thank you for the detailed reply. Now, the problem I see is that the end-users application is crashing after a day whenever he uses synchronous calls. It looks like he is looking to transition to asynchronous calls, but he would like to offer Synchronous calls as well.

Now, I perhaps did not explain myself better in my earlier email or forgot to provide more context so I apologize if it was not clear enough, but the reason for us to look at memory consumption on a "detailed" basis was to identify what was triggering the memory growth. Now, you can leave the application running for a day or two and it will eventually crash as it did for the customer.

Now, would this be true for COM development as well, I am familiar with the garbage collector in .NET but to be honest I have not done to much development with COM. Now, forgive my ignorance, but even if I was going to develop a COM app, Does the toolkit uses .NET runtime in the background so the Garbage collector would still be in place?

Please Log in or Create an account to join the conversation.

More
01 Dec 2021 10:57 #10411 by support
Hello.

It is expected.

As the underlying code is all in .NET, the memory management is non-deterministic. Observing the memory consumption on "detailed" basis makes little sense, and no conclusions can be drawn from it. The only indication of a true memory leak is a continuing memory increase observed over very long time (or so big that it actually eats out the available memory). I had a case where the memory consumption continued to grow for 4-5 days and only after that the .NET garbage collector decided it is time to free it. And that's all fine. In the .NET managed world, developers accustomed to code-driven memory management (like in usual C/C++) need to unlearn big parts what they know about it.

So, the true answer is not precisely "it is expected". The memory could also have behaved differently, and it would still be right. A better answer is "it does not matter". The task of the automated memory management is not to consume as little memory as possible, or fulfill anybody's preconceptions about how much should be consumed at a given point in time.

Best regards

Please Log in or Create an account to join the conversation.

More
30 Nov 2021 21:02 #10410 by Restrepo
Hello Z,

I wanted to run something by you and see if I can get your thought on this. I am currently working with a customer that is experiencing some memory growth when using the OPC UA client object. Now, I believe we figured out why the memory was experienced and just want to run it by you.

We were able to replicate this by adding a While(1) to the ReadValue.Main.cpp Example:

void ReadValue::Main()
{
// Initialize the COM library
CoInitializeEx(NULL, COINIT_MULTITHREADED);
while(1)
{
// Instantiate the client object
_EasyUAClientPtr ClientPtr(__uuidof(EasyUAClient));

// Perform the operation
_variant_t value = ClientPtr->ReadValue(
/*L"opcua.demo-this.com:51211/UA/SampleServer",
L"nsu=http://test.org/UA/Data/;i=10853");*/
L"opc.tcp://10.1.10.72:62541",
L"nsu=urn:inductiveautomation:ignition:opcua:tags ;ns=2;s=[default]/PROCESS/MANAGEMENT/INSTANCE/ADMIN/IsActive");

// Display results
_variant_t vString;
vString.ChangeType(VT_BSTR, &value);
_tprintf(_T("valuem: %s\n"), (LPCTSTR)CW2CT((_bstr_t)vString));
}
// Release all interface pointers BEFORE calling CoUninitialize()
CoUninitialize();
}


It looks like the resources are delay-released, so the memory will start to increase(we monitored the memory using task manager) whenever one reads over 100 values. However, once it pauses one can see the memory drop over several seconds. It looks to me that calling ReadValue() method that fast causes memory growth.

with that in mind I have a few questions:

  • Have you experienced this in the past? If so is this expected? or in other words, are we correct on our assessment?
  • Is there any Documentation talking about the limitation on how fast the ReasValue method can be called?

The customer is using the 5.61 Version of the toolkit. I will be testing with the new version as well so I will get back to you if I can replicate it with the new version as well.

-Rod

Please Log in or Create an account to join the conversation.

Moderators: support
Time to create page: 0.064 seconds