View Issue Details

IDProjectCategoryView StatusLast Update
0003102Compliance Test Tool (CTT) Unified Architecture3 - Feature Requestpublic2019-01-07 17:08
ReporterThomas Reuther Assigned ToAlexander Allmendinger  
PrioritynormalSeveritycrashReproducibilityalways
Status assignedResolutionreopened 
PlatformPC Windows 7 64bitOSWindowsOS Version7 64bit
Target Version1.04 
Summary0003102: CTT crashes due to out of memory when running subscriptions
Description

I run a user defined test script where one subscription monitores 200 items. Those items have a change interval of 10 ms (= hundred values per second). I receive 20,000 data notifications per publish.
Within 100 publish calls the memory of the CTT increases from about 50 MB to 850 MB. I stopped the test after these 100 calls. When I continue then the CTT crashes if the memory consumption increases more than 1.4 GB.
When calling DeleteMonitoredItems / DeleteSubscription the memory will released. After test (100 publish calls) the used memory is 0000068:0000100 MB.

Steps To Reproduce

Subscription parameters:
publishing interval = 1000
Monitored items:
Sampling interval = 0
Queue size = 110 (100 items + 10%)

Additional Information

The test script works fine. But if it runs longer then the CTT crashes due to out of memory. See attached memory graph.

CTT: 1.2.335.238

TagsNo tags attached.
Attached Files
MemoryGraph.png (37,760 bytes)   
MemoryGraph.png (37,760 bytes)   
Files Affected

Activities

Nathan Pocock

2015-11-06 17:28

viewer   ~0006435

Hello Thomas,

I cannot replicate the problem here. I am using a newer CTT that may in fact have the problem resolved already. I would like to send the new CTT to you. Please email me at compliance@opcfoundation.org.

Nathan Pocock

2016-02-12 18:41

viewer   ~0006723

No feedback.
Furthermore, we have released a newer CTT 1.02.336.248 that is a rebuild and should be more stable.

Thomas Reuther

2016-12-12 14:42

reporter   ~0007515

This "bug" still exists in CTT 1.2.336.254

Example: 1 subscription, 1,250 monitored items, 250 ms sampling rate, 1,000 ms publishing interval, queue size = 5.

It takes only a few minutes until the CTT's memory increaes up to 1.7 GB and crashes.

If I use the Java toolkit (from OPC Foundation website) as a client the memory isn't increasing but I get a lot of subscription timeouts.
If I use the .Net toolkit (from OPC Foundation website) everything is working perfectly.

Alexander Allmendinger

2018-08-07 12:50

reporter   ~0009276

This happens due to expected behavior of the CTT. The CTT is keeping for verification purposes all received DataChangeNotifications in memory. This allows test scripts to validate their content afterwards. Of course at some point in time it will reach a memory limitation of the system which will cause it to crash because it can't use any more memory. Because we need to keep that buffer available in the CTT we can't change that behavior and freeing old data. The limitation will be increased from time to time due to changes of the redistributables etc. In my environment the CTT can use up to 2 GB of Memory.

Could you please point out the intend of this test case so we can think about a possible solution by changing the script but still doing the same verification?

Thomas Reuther

2018-08-10 10:10

reporter   ~0009290

Last edited: 2018-08-10 10:13

This test is intended as a performance test.

How can I access all received DataChangeNotifications in memory as you mentioned?
What I do is also to store all received data in memory, and after the subscription has ended I check if I have received all expected data.

I have several sets of test configurations: number of monitored items and updates rates, to measure the performance capabilities of our server. E.g. expected rate is of ~80K data values per second. And I also want to check if the performance is constant over a period of 1h , 8h or 24h (load test).
Today the tests can run savely only up to 25s without crash.

Alexander Allmendinger

2018-08-10 10:53

reporter   ~0009292

You can access them via the PublishHelper object. This Helper object has two elements for the DataChangeNotifications which are
=== PublishHelper.ReceivedDataChanges ===
This element will save all received data change notifications until the subscription is been deleted.
=== PublishHelper.CurrentDataChanges ===
This element will only show the data changes of the last PublishResponse.

I hope this helps a bit. Unfortunately this will only make the CTT run a bit longer because the data then is only kept in the memory once. But I'm pretty sure it still won't run for 24h with this change.
I'll check for an opportunity to empty the array. This would ensure that the CTT stays up and running even though you're going to lose the data in the memory.
Because JavaScript works pretty well with strings I would then recommend to save the desired Information in a file and clean the PublishHelper.ReceivedDataChanges list and do the validation afterwards by interpreting the content of the file.

Thomas Reuther

2018-08-10 11:19

reporter   ~0009296

That's good news to me! So if I manually (by script) empty the list of ReceivedDataChanges, or remove my own variables, then it could be what I need!?!

Sorry for my poor knowledge. I program user defined scripts with CTT for about 4 years now. All I know is what I understood from studying existing scripts. But from a lot of scripts and built-in objects I don't know their intention.

Thomas Reuther

2018-08-13 12:39

reporter   ~0009308

I have fixed my performance tests, but the storage of values of monitored items is not the only issue. After each call of PublishHelper.Execute() I reset the value of ReceivedDataChanges to "[]" (empty array). Unfortunately the CTT is still crashing. So I did more investigation and I found 3 issues:

  1. Call of addError()
  2. Call of writeFile()
  3. Data type conversion using UaVariant.toXxx() methods.

The first line I can accept. CTT needs to show the errors occured. The other two I haven't expected. That piece of code is used to analyze received data and give error if some data is missing.

<code>
var c = mItem.Values[0].Value.toInt32() - 1; // initialize with the gap in the beginning
for (var i=1; i<mItem.Values.length; i++) // look for further gaps
{
c = c + mItem.Values[i].Value.toInt32() - (mItem.Values[i-1].Value.toInt32() + 1);
}
c = c + expectedNumOfValues - mItem.Values[mItem.Values.length-1].Value.toInt32(); // add the gap at the end
if (c > 0)
{
addError("Missing " + c + " values! Expected <" + expectedNumOfValues + "> but got <" + mItem.Values.length + ">. NodeId=\"" + mItem.NodeId + "\"");
writeFile(logDir + "/" + mItem.NodeId.getIdentifierNumeric() + ".txt", mItem.Values.toString());
success = false;
}
</code>

The variable "c" is used to calculate the gaps. The underlying data simulation increases values from "0" to <expectedNumOfValues> by "1". If "c > 0" I know how many values are missing.
Only after removing 3 lines (the for loop, the call of addError() and the call of writeFile()) the memory will not further increase.

Alexander Allmendinger

2018-08-31 15:15

reporter   ~0009327

I'm happy to hear that we already made some progress.

I can see where the increase might comes from. The addError() function does print the error in the result window and therefore the necessary memory increases with each call of this function. Due to your test scenario I assume there are many addError calls in one test run.
If you do not need the information of each failure in the CTT I would suggest to remove the addError() and only save the information in the file. Then checking the success flag at the end and if it is set to false, print one error only.
Let me know if it worked out well.

Issue History

Date Modified Username Field Change
2015-06-29 10:46 Thomas Reuther New Issue
2015-06-29 10:46 Thomas Reuther File Added: MemoryGraph.png
2015-11-06 17:28 Nathan Pocock Note Added: 0006435
2015-11-06 17:28 Nathan Pocock Assigned To => Nathan Pocock
2015-11-06 17:28 Nathan Pocock Status new => feedback
2016-02-12 18:41 Nathan Pocock Note Added: 0006723
2016-02-12 18:41 Nathan Pocock Status feedback => resolved
2016-02-12 18:41 Nathan Pocock Resolution open => no change required
2016-12-12 14:42 Thomas Reuther Note Added: 0007515
2016-12-12 14:42 Thomas Reuther Status resolved => feedback
2016-12-12 14:42 Thomas Reuther Resolution no change required => reopened
2016-12-14 18:18 Nathan Pocock Assigned To Nathan Pocock => Csaba Abram
2016-12-14 18:18 Nathan Pocock Status feedback => assigned
2017-07-13 01:31 Paul Hunkar Assigned To Csaba Abram => Paul Hunkar
2017-07-13 01:31 Paul Hunkar Assigned To Paul Hunkar => Csaba Abram
2018-08-07 12:50 Alexander Allmendinger Note Added: 0009276
2018-08-07 12:50 Alexander Allmendinger Assigned To Csaba Abram => Alexander Allmendinger
2018-08-07 12:50 Alexander Allmendinger Status assigned => feedback
2018-08-10 10:10 Thomas Reuther Note Added: 0009290
2018-08-10 10:10 Thomas Reuther Status feedback => assigned
2018-08-10 10:13 Thomas Reuther Note Edited: 0009290
2018-08-10 10:53 Alexander Allmendinger Note Added: 0009292
2018-08-10 11:19 Thomas Reuther Note Added: 0009296
2018-08-13 12:39 Thomas Reuther Note Added: 0009308
2018-08-31 15:15 Alexander Allmendinger Note Added: 0009327
2019-01-07 17:08 Paul Hunkar Category Implementation Bug => Feature Request
2019-01-07 17:08 Paul Hunkar Target Version => 1.04
2019-01-28 14:14 Paul Hunkar Category Feature Request => 3 - Feature Request