Author |
Message
|
Armageddon123 |
Posted: Mon Apr 28, 2014 12:12 am Post subject: Memory issue with WMB. |
|
|
Acolyte
Joined: 11 Feb 2014 Posts: 61
|
Hi Experts
I need your help on a new memory issue.
I have gone thru the memory issue carefully and have been able to recreate the memory issue with a very small flow.
using MQnput,MQGet and Compute nodes.
Here it is
MQInput- Compute1-MQGet-Compute2-Compute3
Code in Compute1
CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN
CALL CopyMessageHeaders();
-- CALL CopyEntireMessage();
DECLARE K INTEGER 1;
WHILE K < 200 DO
SET OutputRoot.XMLNSC.A.C = 'A';
PROPAGATE ;
SET K= K + 1;
END WHILE;
RETURN FALSE;
END;
Here ,I am just propagating a small , valid xml to next node
In MQGet , Message Domain is set to XMLNSC.
In Compute2 node, it has only one line of code., Saving the xml in Environment
SET Environment.Data= InputRoot.XMLNSC.Data ;
(though this is not the correct method of saving the data in Environment tree, but here we are not much bothered about the data , only the memory.)
In Compute3 node, only one line
SET Environment.Data = NULL ;
So logic is trigger the flow with MQInput with a small message(1 KB message). Propagate 200 times from the Compute1 node. Each time, get a message from the MQGet Queue.
Then save it in Environment and then later ,delete it from the environment. Each xml in MQGet Queue is 500 KB size..
Why the last two compute nodes?- In real flow, once the message from MQGet is saved in Environment, some additional functions are carried out and finally the message is removed from Environment tree.Here , for simplicity, i have removed those things. This sample flow alone is enough to recreate the memory issue
Now in this simple flow, I was expecting that, after each time the flow reaches Compute3 node, the Environment.Data is cleared and so there is no additional storage/memory required when the flow saves the message again in the Environment in the next loop
But as seen from the DataFlowEngine.exe process memory usage, the memory goes up and up and up each time it is looping and the EG reaches the max memory and sometimes abends.
It appears that the statement SET Environment.Data = NULL ; is not serving the purpose of clearing the memory as i thought.
I was of the understanding that the, SET NULL statement will issue a "free" on all its storage and these blocks will be returned to the DataFlowEngines heap for next message.
The xml which MQGet gets is 500 KB xml which is the reason for huge memory usage at first place. but doesn't SET NULL statement clear that all?
Can you please advise me what is the reason for this memory issue in this simple flow.
What code/logic needs to be implemented in the Compute3 node so that the EG memory doesnot go up and up as it goes looping. In other words, how can we code to free the storage in each loop.
Memory Statistics are below for the test run
before tirggering the flow : DataFlowEngine.exe memory - 97,176 K
after triggering the flow:DataFlowEngine.exe memory - 1041,120 K
using WMB 7.0.0.6 |
|
Back to top |
|
 |
smdavies99 |
Posted: Mon Apr 28, 2014 12:20 am Post subject: |
|
|
 Jedi Council
Joined: 10 Feb 2003 Posts: 6076 Location: Somewhere over the Rainbow this side of Never-never land.
|
Have you thought about splitting the flow into pieces?
PROPAGATE to an MQOutput Node.
Then in the second part, do the work as before?
The number of instances of the second flow should allow you to control the memory use? _________________ WMQ User since 1999
MQSI/WBI/WMB/'Thingy' User since 2002
Linux user since 1995
Every time you reinvent the wheel the more square it gets (anon). If in doubt think and investigate before you ask silly questions. |
|
Back to top |
|
 |
Esa |
Posted: Mon Apr 28, 2014 12:22 am Post subject: Re: Memory issue with WMB. |
|
|
 Grand Master
Joined: 22 May 2008 Posts: 1387 Location: Finland
|
Armageddon123 wrote: |
But as seen from the DataFlowEngine.exe process memory usage, the memory goes up and up and up each time it is looping and the EG reaches the max memory and sometimes abends.
It appears that the statement SET Environment.Data = NULL ; is not serving the purpose of clearing the memory as i thought.
I was of the understanding that the, SET NULL statement will issue a "free" on all its storage and these blocks will be returned to the DataFlowEngines heap for next message.
The xml which MQGet gets is 500 KB xml which is the reason for huge memory usage at first place. but doesn't SET NULL statement clear that all?
|
SET NULL doesn't free the memory immediately, it just detaches the element. The memory is released later when the flow instance terminates.
This command releases the memory immediately:
Code: |
DELETE FIELD Environment.Data; |
|
|
Back to top |
|
 |
zpat |
Posted: Mon Apr 28, 2014 12:36 am Post subject: |
|
|
 Jedi Council
Joined: 19 May 2001 Posts: 5866 Location: UK
|
|
Back to top |
|
 |
fjb_saper |
Posted: Mon Apr 28, 2014 7:19 am Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
And I believe he is also hitting a know problem due to the creation of too many parsers. Remember that for any message he is creating 200 parsers (albeit attached to Environment.Data)...  _________________ MQ & Broker admin |
|
Back to top |
|
 |
Esa |
Posted: Mon Apr 28, 2014 10:49 am Post subject: |
|
|
 Grand Master
Joined: 22 May 2008 Posts: 1387 Location: Finland
|
fjb_saper wrote: |
And I believe he is also hitting a know problem due to the creation of too many parsers. Remember that for any message he is creating 200 parsers (albeit attached to Environment.Data)...  |
No, he is not, because he doesn't create a parser under Environment
Armageddon123 wrote: |
SET Environment.Data= InputRoot.XMLNSC.Data ;
(though this is not the correct method of saving the data in Environment tree, but here we are not much bothered about the data , only the memory.) |
But he is obviously planning to do that in the next step...
The InputRoot.XMLNSC parser will be neatly released by the MQGet node, so that's not a problem. |
|
Back to top |
|
 |
Armageddon123 |
Posted: Tue Apr 29, 2014 4:23 am Post subject: |
|
|
Acolyte
Joined: 11 Feb 2014 Posts: 61
|
Hi Esa,
Many thanks for your suggestion to use 'DELETE FIELD'. It is working fine in the sample flow.
Memory statistics for the test run.
Before triggering flow ->DataFlowEngine.exe- 42,452 K
After flow triggered and completed-> DataFlowEngine.exe- 55,896 K . So the memory is not going up and up now in the sample flow.
I will now test this change on the real application complex flow and post the results
I will also update/correct the code which saves xml to Environment tree and test that as well.
Hi smdavies99,
sure, we will think about the alternative designs once we confirm what is the issue with this design(as this is an existing flow, have to explain to the customer the root cause of the issue with present design) . If it gets resolved with the suggestion of Esa, we maynot suggest for a redesign. thnx
Hi fjb_saper,
could you please direct me to the technote or documentation which suggests the issue you mentioned.(" hitting a known problem due to the creation of too many parsers"). It will be helpful when the coding is done for creating the parser on Environment tree. thnx |
|
Back to top |
|
 |
fjb_saper |
Posted: Tue Apr 29, 2014 5:26 am Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
|
Back to top |
|
 |
Armageddon123 |
Posted: Tue Apr 29, 2014 11:39 pm Post subject: |
|
|
Acolyte
Joined: 11 Feb 2014 Posts: 61
|
|
Back to top |
|
 |
Esa |
Posted: Wed Apr 30, 2014 12:16 am Post subject: |
|
|
 Grand Master
Joined: 22 May 2008 Posts: 1387 Location: Finland
|
Thanks, that's a very interesting link.
But I don't think your flow has problems with parsers getting too large. Setting the environment variable would likely have a neglible effect on the memory used by the execution group. But please inform us if not. With the bargain you would get slightly worse performance, because the flow couldn't reuse parsers from the cache and had to create them from scrach every time.
Your MQGet node is creating an XMLNSC parser each time it reads a message, but it should also release it to the pool each time it terminates, so in practice it is reusing the same parser all the time.
I think fjb_saper is referring to a problem called orphaned parsers that happens when you programmatically create parsers within a loop and fail to release them in the pool. In fact you cannot programmatically release a parser, you must design the flow in a manner that makes sure that the releasing happens.
Orphaned parsers are released to the cache pool when the flow instance terminates and AFAIK they can be reused by other flow instances. If your flow orpaned parsers, the net effect would be that the execution group was holding 200 extra parsers in the cache, each of them caching element names and other stuff that uses memory.
Currently your flow doesn't seem to have the orphaned parsers problem. But if you change the flow so that you create an XML parser under Environment before you copy the message in Compute2, it will likely have. You can avoid the problem by creating the parser in Compute1 already and not deleting it within the loop, but the root element under it.
But, on the other hand, 200 parsers is not very much. They would be a real problem if your flow looped for thousands of times. |
|
Back to top |
|
 |
Armageddon123 |
Posted: Fri May 02, 2014 12:10 am Post subject: |
|
|
Acolyte
Joined: 11 Feb 2014 Posts: 61
|
Hi Esa,
Thank you for explaining the orphaned parser issue and its solution.
Infact the application flow had both the issues discussed here(
1. DELETE FIELD
2. new Parser was getting created in each loop).
For the parser issue, I just implemented the method you suggested . (creating a parser before the loop starts.)
Once both the solutions were implemented, it works fine now.
Thank you again for your help. |
|
Back to top |
|
 |
|