Appserver does not clean memory after calling from .Net

okion

New Member
Hi there,

We are calling the appserver via .NET
There for I built a progress gate on the appserver.

DEFINE INPUT-OUTPUT PARAMETER DATASET-HANDLE hp_Dataset.
DEFINE INPUT-OUTPUT PARAMETER DATASET-HANDLE hp_Context.
Main-block:
DO:
END.

For the moment the main block is empty.

Evertime i call that gate, _proapsv.exe memory usage increase a litle.
So at the end the memory is full.

Does anyone know how this can happen?

The server log file says:
That the gate.p is started persistent and and will be deleted.

4 AS AS Server Message state = MSGSTATE_RECVLAST
4 AS AS calling css_conn()
3 AS AS connect requestID= NULL
2 AS AS Application Server connected with connection id: 10.100.0.243::TEST::3097::6c3187dc7fec6128:2d213063:12af88a0fc5:-7dc7. (8358)
3 AS AS ASK Protocol is disabled.
3 AS AS CSS_CONN before ACK, connection=10.100.0.243::TEST::3097::6c3187dc7fec6128:2d213063:12af88a0fc5:-7dc7 bound=0 changed=0
4 AS AS css_conn() ret= 0
4 AS AS Server Message state = MSGSTATE_IDLE
4 AS AS Server Message state = MSGSTATE_INITRQ
4 AS AS Server Message state = MSGSTATE_RECVFIRST
4 AS AS -- TRACE: Open4GLWrite 8192. (8402)
4 AS AS -- TRACE: cso4GL: Before loadProc() (8458)
2 AS AS -- TRACE: PERSISTENT Procedure 'gate.p' START. (5497)
4 AS AS -- TRACE: cso4GL: After successfull loadProc() (8458)
4 AS AS -- TRACE: Set open 4GL server state to 8. (8400)
4 AS AS Server Message state = MSGSTATE_RECVMIDDLE
4 AS AS -- TRACE: Open4GLWrite 8192. (8402)
4 AS AS Server Message state = MSGSTATE_RECVMIDDLE
4 AS AS -- TRACE: Open4GLWrite 8192. (8402)
4 AS AS Server Message state = MSGSTATE_RECVMIDDLE
4 AS AS -- TRACE: Open4GLWrite 8192. (8402)
4 AS AS Server Message state = MSGSTATE_RECVMIDDLE
4 AS AS -- TRACE: Open4GLWrite 8192. (8402)
4 AS AS -- TRACE: Set open 4GL server state to 2. (8400)
4 AS AS Server Message state = MSGSTATE_RECVLAST
3 AS AS requestID= <REQ|O4GL-000005>
4 AS AS -- TRACE: Open4GLWriteLast 344. (8401)
4 AS AS -- TRACE: Open4GLWrite 344. (8402)
4 AS AS Server Message state = MSGSTATE_SENDRESP
4 AS AS -- TRACE: cso4GL: In execProc() - before execution. (8458)
3 AS AS -- TRACE: PERSISTENT Procedure END SUCCESS. (8396)
4 AS AS -- TRACE: cso4GL: In execProc() - successful execution. (8458)
4 AS AS -- TRACE: cso4GL: In execCall() - execProc() success. (8458)
4 AS AS -- TRACE: Set open 4GL server state to 3. (8400)
4 AS AS -- TRACE: Set open 4GL server state to 13. (8400)
4 AS AS -- TRACE: open4GLRead 8192. (8403)
4 AS AS -- TRACE: open4GLRead 8192. (8403)
4 AS AS -- TRACE: open4GLRead 8192. (8403)
4 AS AS -- TRACE: open4GLRead 8192. (8403)
4 AS AS -- TRACE: open4GLRead 8192. (8403)
4 AS AS -- TRACE: Set open 4GL server state to 9. (8400)
4 AS AS -- TRACE: Set open 4GL server state to 1. (8400)
4 AS AS -- TRACE: open4GLRead 2248. (8403)
4 AS AS Server Message state = MSGSTATE_FINISHRQ
4 AS AS Server Message state = MSGSTATE_IDLE
4 AS AS Server Message state = MSGSTATE_INITRQ
4 AS AS Server Message state = MSGSTATE_RECVLAST
3 AS AS requestID= delete(<Progress.Open4GL.DynamicAPI.PersistentProc|Progress.Open4GL.DynamicAPI.Session|gate.p|1>)
4 AS AS -- TRACE: Open4GLWriteLast 12. (8401)
4 AS AS -- TRACE: Open4GLWrite 12. (8402)
4 AS AS -- TRACE: Set open 4GL server state to 6. (8400)
4 AS AS Server Message state = MSGSTATE_SENDRESP
4 AS AS -- TRACE: Set open 4GL server state to 7. (8400)
4 AS AS -- TRACE: Set open 4GL server state to 1. (8400)
4 AS AS -- TRACE: open4GLRead 4. (8403)
4 AS AS Server Message state = MSGSTATE_FINISHRQ
4 AS AS Server Message state = MSGSTATE_IDLE
4 AS AS Server Message state = MSGSTATE_RECVLAST
2 AS AS Application Server disconnected with connection id: 10.100.0.243::TEST::3097::6c3187dc7fec6128:2d213063:12af88a0fc5:-7dc7. (8359)
4 AS AS Server Message state = MSGSTATE_IDLE
 

RealHeavyDude

Well-Known Member
I am not 100% positive on this:

You pass dynamic ProDataSets to and from the AppServer. Dynamics objects, unless specified otherwise, are created in the unnamed widget-pool that is scoped to the session and will therefore be cleaned up when the session ends - in your case when the AppServer agent is shut down.

To alter this behavior you can define an unnamed widget-pool in the procedure that you call on the AppServer and from that moment all dynamic objects are scoped per default to this unnamed widget-pool which is scoped to the procedure and therefore will be cleaned up when the procedure ends.

To achieve this just put the line
CREATE WIDGET-POOL NO-ERROR.
at the top of you procedure.

Heavy Regards, RealHeavyDude.
 

okion

New Member
I found the solution. It seems to be that progress creates temp tables for dynamic stuff.
See: ID: 18848 Title: "Excessive Temp-Table Defintions May Cause Error 40 or 14675"
At the end of each procedure which retrieves the dataset there should be a delete object for each dataset.

In my case:
DELETE OBJECT hp_Dataset.
DELETE OBJECT hp_Context.
 

RealHeavyDude

Well-Known Member
Passing dynamic ProDataSets and Temp-Tables to the AppServer will always create a copy of the dynamic objects on the AppServer - and the default behavior for dynamic objects kicks in - unless otherwise specified, they wind up in the unnamed widget pool of the Progress session. The rule for all handle-based dynamic objects is: You control the lifecycle of these objects - you create them, you delete them.

Whether you delete the objects manually with the DELETE OBJECT statement or you utilized widget pools for that is up to you - I find the latter one more obvious and water tight. (What's of interest here is that the OUTPUT parameter is passed back after, code-wise, the DELETE statement takes place. AFAIK the 4GL postpones that deletion for you so that the OUTPUT parameters will contain what you expect them to.) It's just that knowledge about widget pools is not widely spread within the Progress community ...


Heavy Regards, RealHeavyDude.
 
Top