Feedback
 
Did this article resolve your question/issue?

   

Your feedback is appreciated.

Please tell us how we can make this article more useful. Please provide us a way to contact you, should we need clarification on the feedback provided or if you need further assistance.

Characters Remaining: 1025

 


Article

How to check for leaked dynamic objects programmatically?

« Go Back

Information

 
Article Number000011782
EnvironmentProduct: OpenEdge
Version: 9.x
Version: 10.x, 11.x
OS: All Supported Operating Systems
Other: AppServer
Question/Problem Description
How to check for leaked dynamic objects programmatically?
How to programmatically detect objects that are left in memory?

When using dynamic objects it is easy to forget to clean up all of the objects that the application code creates.  This can cause memory leak issues which more can easily show up in AppServer and Webspeed environments where programs are executed millions of times each day.

This Article provides a simple code example which can be used to detect whether the application code is leaking memory due to objects not being cleaned up and this information can then be used to narrow down the scope of the debugging that needs to be carried out.

 
Steps to Reproduce
Clarifying Information
Error Message
Defect/Enhancement Number
Cause
Resolution

The following code example can be used to detect objects which are left in memory.

  • This code is most useful for debugging memory leaks on AppServer and Webspeed agents
  • The objects that can be checked are those exposed by the SESSION:FIRST-* properties.
  • Walks the widget trees that the ABL makes available and dumps out basic information on the objects which have been left in memory.
  • Since it runs within a single OpenEdge session (client, AppServer agent, WebSpeed agent), it will only report objects for that specific session.
  • This code uses the MESSAGE statement to ensure that when run on the AppServer the results will be available in the AppServer server log file (assuming, that the loggingLevel is set to either Verbose or Extended).
  • The code inside of each DO WHILE block can be changed into the appropriate DELETE statement in order to make this program into a quick & dirty tool to release leaked resources on the AppServer so that the AppServer does not have to be shut down and restarted.  Just make the code change then from a 4GL client, run this program on the AppServer.
  • This code was designed to work on OpenEdge 10.1x and later releases. To use this code with an older release, remove the code that references SESSION attributes that do not exist in earlier releases.
DEFINE VARIABLE hTemp   AS HANDLE               NO-UNDO.
DEFINE VARIABLE hObject AS HANDLE               NO-UNDO.
DEFINE VARIABLE vTemp   AS CHARACTER            NO-UNDO.
DEFINE VARIABLE oObject AS Progress.Lang.Object NO-UNDO.
DEFINE VARIABLE oTemp   AS Progress.Lang.Object NO-UNDO.

ASSIGN hObject = SESSION:FIRST-DATASET.
DO WHILE hObject <> ?:
    ASSIGN hTemp   = hObject
           hObject = hObject:NEXT-SIBLING.
    MESSAGE 'ProDataSet, Handle=' hTemp
                        ', Name=' hTemp:NAME
                     ', Dynamic=' hTemp:DYNAMIC VIEW-AS ALERT-BOX.
END.

ASSIGN hObject = SESSION:FIRST-DATA-SOURCE.
DO WHILE hObject <> ?:
    ASSIGN hTemp   = hObject
           hObject = hObject:NEXT-SIBLING
           vTemp   = (IF hTemp:QUERY = ? THEN ? ELSE hTemp:QUERY:PREPARE-STRING).
    MESSAGE 'DataSource, Handle=' hTemp
                        ', Name=' hTemp:NAME
                       ', Query=' vTemp VIEW-AS ALERT-BOX.
END.

ASSIGN hObject = SESSION:FIRST-BUFFER.
DO WHILE hObject <> ?:
    ASSIGN hTemp   = hObject
           hObject = hObject:NEXT-SIBLING.
    MESSAGE 'Buffer, Handle=' hTemp
                    ', Name=' hTemp:NAME
                   ', Table=' hTemp:TABLE
                 ', Dynamic=' hTemp:DYNAMIC
                 ', DataSet=' hTemp:DATASET VIEW-AS ALERT-BOX.
END.

ASSIGN hObject = SESSION:FIRST-PROCEDURE.
DO WHILE hObject <> ?:
    ASSIGN hTemp   = hObject
           hObject = hObject:NEXT-SIBLING.
    MESSAGE 'Procedure, Handle='hTemp
                      ', Name=' hTemp:NAME VIEW-AS ALERT-BOX.
END.

ASSIGN hObject = SESSION:FIRST-QUERY.
DO WHILE hObject <> ?:
    ASSIGN hTemp   = hObject
           hObject = hObject:NEXT-SIBLING.
    MESSAGE 'Query, Handle=' hTemp
                   ', Name=' hTemp:NAME
                ', Dynamic=' hTemp:DYNAMIC
                  ', Query=' hTemp:PREPARE-STRING VIEW-AS ALERT-BOX.
END.

ASSIGN oObject = SESSION:FIRST-OBJECT.
DO WHILE oObject <> ?:
    ASSIGN oTemp   = oObject
           oObject = oObject:NEXT-SIBLING.
    MESSAGE 'Object, Name=' oTemp:ToString() VIEW-AS ALERT-BOX.
END.

In addition to the above, the Dynamic Objects View of the Debugger allows tracking the creation of dynamic handle-based ABL objects such as dynamic queries and buffers, and persistent procedures.  This allows verification that these objects are being deleted as needed and that application code is not creating memory leaks by leaving objects running when they’re no longer used.

The following tutorial demonstrates:
  1. How to use the Dynamic Objects View 
  2. How to enable dynamic object monitoring from Architect: 
After recording these videos the name for OpenEdge Architect was changed to Progress Developer Studio for OpenEdge (PDSOE). As you view these videos, especially if you are working with OpenEdge 11.0 or later, please keep this name change in mind.

https://community.progress.com/community_groups/openedge_general/w/openedgegeneral/1197.openedge-architect-video-monitoring-dynamic-objects-in-the-debugger


 
Workaround
Notes
Attachment
Last Modified Date7/15/2019 7:58 AM