Did this article resolve your question/issue?



How to force application garbage collection?

« Go Back


TitleHow to force application garbage collection?
URL Name000037476
Article Number000159283
EnvironmentProduct: OpenEdge
Version: 10.x, 11.x, 12.x
OS: All supported platforms
Question/Problem Description
How to programmatically force activation of the garbage collector in an application?
How to force application garbage collection of .Net objects
Steps to Reproduce
Clarifying Information
Error Message
Defect/Enhancement Number

To force garbage collection of .Net objects:

  • An ABL process has no control over when the .NET Garbage Collector does its work.
  • .Net garbage collection is performed asynchronously in another thread and is delayed until there are enough objects to collect.
  • With ABL garbage collection there is no way to directly force this to happen with ABL code. 
  • It is advisable to upgrade to at least OpenEdge 11.7.4 where more recent fixes for references to .Net objects are when deleting ABL classes to be available for garbage collection, details are provided in the following Articles:
  • Memory leak when a Progress Class implements a .NET interface   
  • Memory leak when using nested method calls.

For further information on the garbage collection of .Net Objects, review the following Articles which expand on the information above:


ABL Garbage Collection:

  • Unlike .Net garbage collection, ABL Garbage Collection is performed synchronously in the same thread running the application.  
  • When there are no more references to an object in the session, then the ABL garbage collector removes the object (almost) immediately.  
  • The only specific place where ABL garbage collection is forced to happen is on return from an AppServer call (deactivate procedure).  The product specification states:
"When an object's reference count goes to zero, it will be placed on a list of objects to garbage collect. The system will check for objects to garbage collect at regular intervals. The interval used and the order in which objects are destroyed is indeterminate. However, on an AppServer, garbage collection is guaranteed to run before the switch to a different connection context. This ensures that an object’s destructor will always run within the same connection context in which it was created." 
For further discussion specific to ABL Garbage Collection, refer to Article:

To determine when an object is deleted by the Garbage Collector 

Use -clientlog with -logginglevel set to 2 or above and -logentrytypes Dynobjects.* logging.  For example:

prowin.exe -clientlog mylog.lg -logginglevel 2 -logentrytypes DB.Connects,4GLTrace,QryInfo,DynObjects.*,ProEvents.Other:4

4GLTrace and DynObjects.* client logging will write messages:

2 4GL DYNOBJECTS Deleted-by-GC Progress.Lang.Object Handle:16992 (Inic xpyfas @ 187) base_1 
2 4GL DYNOBJECTS Deleted-by-GC .NET Object Handle:18576 (Inic xpyfas @ 208) 

Dynobjects logging is useful to determine what is leaking:

A code example to walk the widget tree of dynamic objects that have been leaked by the session:

As an alternative to client logging, use the LOG-MANAGER system handle:

  • This method requires predetermined code changes.  
  • While client log + dynobjects is useful when a session-wide trace log is required, this logging is switched on and off by statements compiled into the code and is therefore useful to narrow down code blocks in specific application areas:


ABL Reference: Handle Attributes and Methods Reference - LOG-ENTRY-TYPES attribute   

Last Modified Date11/20/2020 6:50 AM
Disclaimer The origins of the information on this site may be internal or external to Progress Software Corporation (“Progress”). Progress Software Corporation makes all reasonable efforts to verify this information. However, the information provided is for your information only. Progress Software Corporation makes no explicit or implied claims to the validity of this information.

Any sample code provided on this site is not supported under any Progress support program or service. The sample code is provided on an "AS IS" basis. Progress makes no warranties, express or implied, and disclaims all implied warranties including, without limitation, the implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample code is borne by the user. In no event shall Progress, its employees, or anyone else involved in the creation, production, or delivery of the code be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample code, even if Progress has been advised of the possibility of such damages.