On 06.07.2022 22:49, Rick McGuire wrote:

On Wed, Jul 6, 2022 at 3:03 PM Rony <rony.flatsc...@wu.ac.at> wrote:

    While debugging potential memory leaks I could narrow one down to the 
currently not tested
    hypothesis that if interpreter instances get terminated it may be the case 
that either the
    .local contained objects or the destination objects of the .local monitors 
do not release the
    references such that no uninit method runs.

    Background: in BSF4ooRexx whenever a ScriptEngine instance gets created an 
ooRexx interpreter
    instance gets created in which the .local monitors get redirected to Java‘s 
System.in,
    System.out and System.err. This occurs by wrapping up these Java objects as 
BSF objects which
    then get used to set the destinations for the .input, .output, .error, 
.traceoutput and
    .debuginput monitors. Upon termination of these ooRexx interpreter instance 
these BSF objects
    should get unreferenced such that their uninit methods can run which remove 
the reference to
    their peer Java objects in the Java registry, allowing them to be garbage 
collected on the
    Java side. This seems to not happen.

    After having come up with a Java registry analyze class plus a garbage 
collector BIF on the
    ooRexx side I have become able to get a raw overview about the area where 
running hundreds, if
    not thousands of ooRexx interpreter instances (each JSP request will cause 
an ooRexx
    interpreter instance to be created to process the Rexx-JSPs) causes 
continuous memory
    consumption on the Java side. Carrying out the redirections of the .local 
monitors  manually
    to and from Java shows that the reference counting via the uninit works and 
no memory leaks occur.

    So, is it possible that either .local or the destination objects of the 
contained monitors do
    not get freed if an ooRexx interpreter instance gets terminated? (Thinking 
about this, I need
    to verify tomorrow that the instances get explicitly terminated, did not 
double-check that today.)

O.K. the Rexx interpreter engines do not get terminated, which explains the ever growing memory consumption and over time slow-down! This is good as then it is clear that the problem is mostlikely not rooted in ooRexx, but either in BSF4ooRexx or (more likely) in the taglib that causes the Rexx interpreter instances to be created (which each needs to be cached until the entire JSP got processed).

Here a glimpse to the relevant debug info (after some stress tests) coming from the Java side, where "REXX_ENGINE" refers to Rexx interpreter instances referrable from Java, and "REXX_PROXY" refers to Rexx objects boxed in Java RexxProxy objects:

   "RexxCleanupRef Report"


   RexxCleanupRef [2022-07-07 14:49:04.755000000] [State as of: 
2022-07-07T14:49:04.755]
          RefKind:         Instances:         Finalized: Not Yet Finalized:
   -----------------------------------------------------------------------
   [TEST].......: [               0] [               0] [               0]
   [REXX_ENGINE]: [           3,579] [               0] [           3,579]
   [REXX_PROXY].: [          35,789] [          35,211] [             578]
   -----------------------------------------------------------------------
   Totals.......: [          39,368] [          35,211] [           4,157]

So it shows that the Rexx interpreter instances in that process do not get terminated, because they do not get finalized on the Java side (there are still Java references in existence).

(It is actually quite amazing how performant ooRexx still is under such heavy 
load conditions.)

The reference to the .local directory is most definitely released upon instance termination. Note, however, that this happens AFTER the end-of-instance garbage collection and uninit pass, since it is necessary to run the uninit methods in a fully functional interpreter instance. And NO, adding an additional garbage collection cycle after that is not the answer. GC cycles are very expensive and really should be avoided as much as possible.

Yes, indeed!

In this particular case (debugging possible memory leaks) it is sometimes really necessary to be able to run gc right before starting a new test cycle. The other use case would be in situations where one has 7/24 programs that do not create too many objects, but if so pinning down system resources such that when going out of scope it may be - under edge-cases, exceptional use cases - important to have it available. (It is like in the Java case where System.gc() allows for having the garbage collector execute which is very helpful in debug scenarios, but otherwise never really needed. But having this method available is important.)

[If documenting the warning clearly and pointing at debugging in the context of external pinned resources may be sufficient to have programmers only use it in debugging and edge cases so not to negatively impact ooRexx performance.]

Anyway, sorry for the noise and thanks for the consideration!

---rony

_______________________________________________
Oorexx-devel mailing list
Oorexx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/oorexx-devel

Reply via email to