Applying your patch and re-running the problematic test-cases, it seems to be 
indeed the case that
the problem is solved! Many thanks!

---rony


On 30.04.2017 13:00, Rony G. Flatscher wrote:
> On 30.04.2017 12:53, Rick McGuire wrote:
>> I want to verify something first. In this scenario, Rexx code makes a call 
>> to a Java method
>> (i.e., the parser) which then makes a lot of callbacks all on the same 
>> thread?
> Yes.
>
>> If so, then I think I might see where the problem could be. The code that 
>> handles nested thread
>> attaches (that is, attaching to a thread that already exists) appears to 
>> hold on to any allocated
>> objects until it returns to the original exit point (in your case, the 
>> initial call to the parser). 
>>
>> This may take a little while to figure out the details of a fix, but I at 
>> least know where to
>> start. You might want to open a bug indicating there appears to be an
>> AttachThread()/DetachThread() memory leak.
> Opened a bug: <https://sourceforge.net/p/oorexx/bugs/1445/>.
>
> ---rony
>
>>
>> On Sun, Apr 30, 2017 at 6:38 AM, Rony G. Flatscher <rony.flatsc...@wu.ac.at
>> <mailto:rony.flatsc...@wu.ac.at>> wrote:
>>
>>     Having slept I went over the debug statements, just to learn that I 
>> concluded wrongly
>>     yesterday: the reference decreases did not come from the Rexx objects 
>> with uninits, but from
>>     the Java side! :(
>>
>>     With new debug statements on the Rexx side (in the destructores) it is 
>> clear that no proxy
>>     Rexx object turns into garbage before the program gets interrupted with 
>> a syntax error.
>>
>>     Will start over analyzing the codepaths, creating debug programs and 
>> report back, once I am
>>     done, which might take a day or two.
>>
>>     ---rony
>>
>>
>>     On 29.04.2017 21:53, Rick McGuire wrote:
>>>
>>>
>>>     On Sat, Apr 29, 2017 at 3:43 PM, Rony G. Flatscher 
>>> <rony.flatsc...@wu.ac.at
>>>     <mailto:rony.flatsc...@wu.ac.at>> wrote:
>>>
>>>         The class object (for the BSF class and also its subclasses) is 
>>> (get) created in the
>>>         BSF.CLS package, which gets required. So it (and its subclasses) 
>>> should get created only
>>>         once in this test case.
>>>
>>>         The ooRexx peer objects are instances of the .BSF class, which 
>>> defines an uninit method.
>>>
>>>         Ad interpreter safepoints:
>>>
>>>           * in this case there is a pending external Rexx function call 
>>> that kicks of the SAX
>>>             parser's parsing and only will return after the SAX parser 
>>> concluded its work,
>>>           * in the meantime each callback from the SAX parser will cause a 
>>> call via JNI to Rexx,
>>>             where each such callback will do an AttachThread() in native 
>>> code and before
>>>             returning a DetachThread().
>>>
>>>         The uninits run, so these interpreter safepoints should be reached.
>>>
>>>     The return from the ooRexx code at the end of the event call is one 
>>> safepoint, but the
>>>     arguments you passed will still be protected at this point. However, 
>>> these objects will not
>>>     be processed until the next time a garbage collection is required and 
>>> then not until the
>>>     next uninit point is hit. 
>>>
>>>      
>>>
>>>         ---
>>>
>>>         Maybe one more thing: the ooRexx peer objects that get created in 
>>> native code are stored
>>>         in a RexxArray object as they server as arguments for the 
>>> SendMessage() function. So I
>>>         assume (pure speculation!) that first the RexxArray object needs to 
>>> get destroyed in
>>>         order for its contained objects to become eligible for destruction. 
>>> Maybe that explains
>>>         why the Rexx peer objects currently do not get their uninits run at 
>>> a much faster pace.
>>>
>>>
>>>     I doubt this causes much of the delay, since these objects don't get 
>>> moved to the uninit
>>>     queue until the next time it is necessary to run the garbage collector. 
>>> It is highly
>>>     unlikely that more than a few objects would be affected  by this, but 
>>> you might give it a
>>>     try and see what happens. 
>>>
>>>     Rick
>>>      
>>>
>>>         ---rony
>>>
>>>
>>>
>>>         On 29.04.2017 21:32, Rick McGuire wrote:
>>>>         Running the garbage collector will not force the uninit methods to 
>>>> be run. When the
>>>>         garbage collector runs, any newly dead objects with uninit methods 
>>>> are marked as being
>>>>         ready to have the uninit method run. At some later time, when the 
>>>> interpreter is at a
>>>>         safe point, then the objects with pending uninit methods will be 
>>>> processed. These are
>>>>         major boundaries such as return from a method or call or thread 
>>>> termination. 
>>>>
>>>>         Since you are creating class objects, things can get delayed even 
>>>> further since the
>>>>         class object will not become "dead" until all of its instances are 
>>>> first "dead". It
>>>>         then gets moved to the uninit queue for processing. 
>>>>
>>>>         Rick
>>>>
>>>>         On Sat, Apr 29, 2017 at 3:11 PM, Rony G. Flatscher 
>>>> <rony.flatsc...@wu.ac.at
>>>>         <mailto:rony.flatsc...@wu.ac.at>> wrote:
>>>>
>>>>             Today, I have started to analyze the code-paths through 
>>>> BSF4ooRexx (Java, c++,
>>>>             ooRexx-package BSF.CLS).
>>>>
>>>>             As I have not found any "obvious" cause for the observed 
>>>> behaviour yet, I have
>>>>             started to analyse the changes in the Java registry (that I 
>>>> have full control of).
>>>>
>>>>             Maybe first a sketch, how Java objects get proxied by ooRexx 
>>>> objects:
>>>>
>>>>               * a Java object that is to be sent to ooRexx as a return or 
>>>> argument value will
>>>>                 get stored together with a reference counter in a Java 
>>>> registry (using a
>>>>                 ConcurrentHashMap), the index is a string which will get 
>>>> passed on to Rexx
>>>>                 instead of the Java object,
>>>>               * the Rexx side will create an instance of the class .BSF 
>>>> (or a subclass of it)
>>>>                 supplying the Java object's index string which is used as 
>>>> the objecname for the
>>>>                 ooRexx peer object
>>>>                   o The BSF class has a destructor method (uninit) which 
>>>> will cause a call to
>>>>                     the Java side to reduce the Java object's reference 
>>>> counter; if the Java
>>>>                     reference counter drops to 0 the Java object will be 
>>>> removed from the Java
>>>>                     registry
>>>>
>>>>             Running the SAX-example serving as the test case until 250 
>>>> startElement
>>>>             SAX-callbacks (each callback from Java to Rexx will cause an 
>>>> AttachThread(),
>>>>             creating the ooRexx peer objects for the arguments, sending 
>>>> the Rexx message, upon
>>>>             return doing a DetachThread()) have been carried out (in 
>>>> addition there are plenty
>>>>             of other SAX-callbacks) and using debug statements for adding 
>>>> and removing entries
>>>>             to/from the Java registry, this is what I can observe:
>>>>
>>>>               * the ooRexx destructors run,
>>>>               * *however* the rate of new ooRexx peer objects that get 
>>>> created (by Java objects
>>>>                 that are sent to Rexx) is much higher than the rate of 
>>>> ooRexx peer objects that
>>>>                 get garbage collected by ooRexx, which causes a continuous 
>>>> increase in Rexx
>>>>                 objects over time
>>>>                   o indeed, the ooRexx peer objects get destroyed 
>>>> eventually, causing the Java
>>>>                     refcounters to be decreased
>>>>                       + it seems that not all ooRexx peer objects that 
>>>> have turned into garbage
>>>>                         get destroyed in the garbage collection runs
>>>>                   o still (hence), the amount of ooRexx peer objects 
>>>> increases quickly at
>>>>                     runtime as the flux of callbacks from Java continues
>>>>               * at the end of the program (in this case forcing an error 
>>>> to stop it by issuing
>>>>                 a 'say 1/0') all uninits run the reference counters on the 
>>>> Java objects in the
>>>>                 Java registry drop to 0!
>>>>
>>>>             Is there a way in ooRexx to have the garbage collector be run 
>>>> (like in Java's
>>>>             System.gc() or Runtime.getRuntime.gc())?
>>>>
>>>>             Such a possibility might help to debug/tame this "run-away" 
>>>> scenario.
>>>>
>>>>             ---rony
>>>>
>>>>
>>>>
>>>>             On 27.04.2017 16:56, Rony G. Flatscher wrote:
>>>>>
>>>>>             Thank you! Will report back, once I concluded the analysis, 
>>>>> which may take a while.
>>>>>
>>>>>             ---rony
>>>>>
>>>>>
>>>>>             On 27.04.2017 16:53, Rick McGuire wrote:
>>>>>>             The memory manager will force any pending uninits to be run 
>>>>>> before it gives up
>>>>>>             and issues the out of resources error messages. I really 
>>>>>> suspect something in the
>>>>>>             way your code is creating the proxies and tracking them is 
>>>>>> preventing the objects
>>>>>>             from being identified as dead objects, so these objects will 
>>>>>> just keep
>>>>>>             accumulating. The more live objects locked in memory, the 
>>>>>> longer a GC cycle will
>>>>>>             take because there is a larger live set to mark. 
>>>>>>
>>>>>>             Rick
>>>>>>
>>>>>>             On Thu, Apr 27, 2017 at 10:34 AM, Rony G. Flatscher 
>>>>>> <rony.flatsc...@wu.ac.at
>>>>>>             <mailto:rony.flatsc...@wu.ac.at>> wrote:
>>>>>>
>>>>>>                 Further information, using the initial e-mail to keep 
>>>>>> all relevant
>>>>>>                 information in one e-mail.
>>>>>>
>>>>>>                 Today I uninstalled the 32-bit ooRexx 5.0beta and 
>>>>>> installed the 64-bit ooRexx
>>>>>>                 5.0beta (both from SourceForge, downloaded February 4th 
>>>>>> 2017).
>>>>>>
>>>>>>                 This time the program ran successfully to the end:
>>>>>>
>>>>>>                   * there were more than 247,000 XML elements processed
>>>>>>                       o as already mentioned this may translate into 
>>>>>> million(s) call backs
>>>>>>                         from Java to Rexx as all SAX events will cause 
>>>>>> callbacks to Rexx
>>>>>>                           + some of these callbacks carry Java objects 
>>>>>> as arguments which
>>>>>>                             will get wrapped as a peer ooRexx object 
>>>>>> (ultimately an instance
>>>>>>                             of the class .BSF that has an uninit method 
>>>>>> defined), namely the
>>>>>>                             Java types: "char[]", "Attributes", "Local" 
>>>>>> from the callbacks 
>>>>>>                             
>>>>>> <https://docs.oracle.com/javase/7/docs/api/org/xml/sax/ContentHandler.html
>>>>>>                             
>>>>>> <https://docs.oracle.com/javase/7/docs/api/org/xml/sax/ContentHandler.html>>
>>>>>>                           + there are no return values (all callbacks 
>>>>>> are defined to be void)
>>>>>>
>>>>>>                   * it took a total of 2:37 hours to SAX-parse a 10MB 
>>>>>> XML file,
>>>>>>                       o the SAX-parsing was over after 1:45 hours
>>>>>>                           + the program constantly slowed down and in 
>>>>>> between paused for a
>>>>>>                             while (which got longer and longer over time)
>>>>>>                       o after the SAX-parseing was over the Rexx program 
>>>>>> needed another  0:52
>>>>>>                         hours to complete
>>>>>>                           + speculating/assuming that in this time all 
>>>>>> the uninits got
>>>>>>                             executed (which is fine)
>>>>>>
>>>>>>                   * it consumed 8.7GB of memory
>>>>>>                       o ProcessExplorer reports a
>>>>>>                           + Physical Memory "PeekWorking Set" of 
>>>>>> 8.795.796 K
>>>>>>                           + Virtual Memory "Virtual Size" of 13.404.424 
>>>>>> K with "Peak Private
>>>>>>                             Bytes" of 9.138.664 K
>>>>>>
>>>>>>                   * it used 24% of the CPU over all 2:37 hours
>>>>>>                       o ProcessExplorer reports a
>>>>>>                           + "Kernel Time" of 0:01:10.184
>>>>>>                           + "User Time" of 2.32.57.960
>>>>>>                           + "Total Time" of  2:34:08.144
>>>>>>                           + "Cycles": 23.898.290.997.693
>>>>>>
>>>>>>                 Will check the BSF4ooRexx call and code paths.
>>>>>>
>>>>>>                 ---rony
>>>>>>
>>>>>>
>>>>>>
>>>>>>                 On 26.04.2017 20:28, Rony G. Flatscher wrote:
>>>>>>>
>>>>>>>                 A student is using BSF4ooRexx to parse a huge XML file 
>>>>>>> using Java's SAX parser.
>>>>>>>
>>>>>>>                 The SAX (simple API for XML) works with a callback 
>>>>>>> concept. In order to be
>>>>>>>                 eligible for these SAX callbacks the ContentHandler 
>>>>>>> interface
>>>>>>>                 
>>>>>>> <https://docs.oracle.com/javase/7/docs/api/org/xml/sax/ContentHandler.html>
>>>>>>>                 
>>>>>>> <https://docs.oracle.com/javase/7/docs/api/org/xml/sax/ContentHandler.html>
>>>>>>>                 must be implemented, which the Rexx program does with 
>>>>>>> the help of BSF4ooRexx.
>>>>>>>
>>>>>>>                 As a result each single SAX event will cause an 
>>>>>>> appropriate Rexx message to
>>>>>>>                 be generated and dispatched.  The Rexx message is named 
>>>>>>> after the
>>>>>>>                 ContentHandler method name and will receive all 
>>>>>>> arguments documented there.
>>>>>>>                 All arguments are processed in native code, a Rexx 
>>>>>>> array object will get
>>>>>>>                 created from the Java arguments.
>>>>>>>
>>>>>>>                 This works and was presented on one of the 
>>>>>>> International Rexx symposiums and
>>>>>>>                 has become part of my lecture using Java camouflaged as 
>>>>>>> ooRexx with the help
>>>>>>>                 of BSF4ooRexx. Here is a link to the symposium which 
>>>>>>> contains links to the
>>>>>>>                 slides: <http://rexxla.org/events/2013/schedule.html>
>>>>>>>                 <http://rexxla.org/events/2013/schedule.html>.
>>>>>>>
>>>>>>>                 Now, a student is in the need to parse a rather huge 
>>>>>>> XML file (10 MB) and
>>>>>>>                 uses the SAX parser. She always hits the Rexx "Error 5: 
>>>>>>> System resources
>>>>>>>                 exhausted"! I asked her to come up with a very small 
>>>>>>> program to demonstrate
>>>>>>>                 the error and I am able to reproduce it reliably!
>>>>>>>
>>>>>>>                 Here is the rather short Rexx program:
>>>>>>>                 --- #!/usr/bin/rexx parse arg xmlFile if xmlFile="" then
>>>>>>>                 XMLFile="..\LB-HB.onlb" if 
>>>>>>> sysFileExists(xmlFile)=.false then do say "File"
>>>>>>>                 pp(xmlFile) "does not exist, aborting." exit -1 end
>>>>>>>                 rexxObject=.saxHandler~new();
>>>>>>>                 
>>>>>>> javaProxy=BSFCreateRexxProxy(rexxObject,,"org.xml.sax.ContentHandler")
>>>>>>>                 
>>>>>>> parser=bsf.loadClass("org.xml.sax.helpers.XMLReaderFactory")~createXMLReader
>>>>>>>                 parser~setContentHandler(javaProxy) eh=.errorHandler~new
>>>>>>>                 
>>>>>>> javaEH=BsfCreateRexxProxy(eh,,"org.xml.sax.ErrorHandler")
>>>>>>>                 parser~setErrorHandler(javaEH) signal on syntax 
>>>>>>> start=.dateTime~new say
>>>>>>>                 pp(start)": start of parsing" parser~parse(XMLFile) 
>>>>>>> end=.dateTime~new say
>>>>>>>                 pp(end)": end of parsing" say "done, needed:" 
>>>>>>> pp(end-start) exit syntax: say
>>>>>>>                 "error at" rexxObject~nrOfElements "element" 
>>>>>>> co=condition('o') say
>>>>>>>                 ppCondition2(co) ::requires "BSF.CLS" /* get the Java 
>>>>>>> support */ ::requires
>>>>>>>                 "rgf_util2.rex" ::CLASS "SaxHandler" -- a Rexx content 
>>>>>>> handler
>>>>>>>                 ("org.xml.sax.ContentHandler") ::attribute nrOfElements 
>>>>>>> ::METHOD init
>>>>>>>                 --ooRexx constructor expose nrOfElements nrOfElements=0 
>>>>>>> ::METHOD
>>>>>>>                 startElement expose nrOfElements USE ARG uri, 
>>>>>>> localName, qName, attributes
>>>>>>>                 nrOfElements+=1 if nrOfElements//1000=0 then say 
>>>>>>> nrOfElements "elements so
>>>>>>>                 far ..." ::METHOD characters -- the callback method for 
>>>>>>> characters (text)
>>>>>>>                 USE ARG charArray, start, length ::METHOD endElement 
>>>>>>> USE ARG uri, localName,
>>>>>>>                 qName, attributes ::method unknown ::class ErrorHandler 
>>>>>>> ::method unknown use
>>>>>>>                 arg methName, argArray exception=argArray[1]s 
>>>>>>> .error~say(methName": "
>>>>>>>                 "line="exception~getLineNumber 
>>>>>>> ",col="exception~getColumnNumber": "
>>>>>>>                 pp(exception~getMessage)) ---
>>>>>>>                 As you might see, there is nothing "special" going on 
>>>>>>> here, other than being
>>>>>>>                 able to supply a Rexx object as the callback object for 
>>>>>>> the Java implemented
>>>>>>>                 SAX parser! It seems that running all these callback 
>>>>>>> from Java to Rexx will
>>>>>>>                 cause eventually that ooRexx gets exhausted of system 
>>>>>>> resources. While
>>>>>>>                 running the program it can be observed that from time 
>>>>>>> to time there are
>>>>>>>                 little lags as if some garbage collecting takes place. 
>>>>>>> Eventually the error
>>>>>>>                 5 is thrown, while executing in native code:
>>>>>>>
>>>>>>>                     result_obj=rtc->SendMessage(ro, c_msg, ra); // with 
>>>>>>> arguments
>>>>>>>
>>>>>>>                 Please note that the following error message only gives 
>>>>>>> the numbers of XML
>>>>>>>                 elements that the SAX parser reported. In reality, 
>>>>>>> *all* callbacks are
>>>>>>>                 carried out from Java to Rexx, the unprocessed ones 
>>>>>>> will be intercepted by
>>>>>>>                 the Rexx UNKNOWN method. So there is a flurry of 
>>>>>>> context switches and
>>>>>>>                 creation of Rexx array objects for the arguments and 
>>>>>>> the like. Here is the
>>>>>>>                 error message on my system.
>>>>>>>                 --- 83000 elements so far ... 84000 elements so far ... 
>>>>>>> error at 84926
>>>>>>>                 element [ADDITIONAL] =[an Array (2 items) 
>>>>>>> id#_-1457160369]
>>>>>>>                 ["BSF4ooRexx/routine/BSF(), error 3: Java exception 
>>>>>>> occurred:
>>>>>>>                 [org.rexxla.bsf.engines.rexx.RexxException:
>>>>>>>                 BSF4ooRexx/routine/jniRexxSendMessageToRexxObject(), 
>>>>>>> error 4:" || "0A"x || "
>>>>>>>                 *-* Compiled method ""OBJECTNAME="" with scope 
>>>>>>> ""Object""." || "0A"x ||
>>>>>>>                 "Error 5 running C:\Program Files 
>>>>>>> (x86)\BSF4ooRexx\BSF.CLS line 2644: System
>>>>>>>                 resources exhausted." || "0A"x || "Error 5.0: message 
>>>>>>> n/a]"]
>>>>>>>                 [org.rexxla.bsf.engines.rexx.RexxException@182d820 
>>>>>>> id#_-1478994985] [CODE]
>>>>>>>                 =[40.900] [CONDITION] =[SYNTAX] [DESCRIPTION]=[] 
>>>>>>> [ERRORTEXT] =[Incorrect
>>>>>>>                 call to routine.] [INSTRUCTION]=[SIGNAL] [MESSAGE]
>>>>>>>                 =["BSF4ooRexx/routine/BSF(), error 3: Java exception 
>>>>>>> occurred:
>>>>>>>                 [org.rexxla.bsf.engines.rexx.RexxException:
>>>>>>>                 BSF4ooRexx/routine/jniRexxSendMessageToRexxObject(), 
>>>>>>> error 4:" || "0A"x || "
>>>>>>>                 *-* Compiled method ""OBJECTNAME="" with scope 
>>>>>>> ""Object""." || "0A"x ||
>>>>>>>                 "Error 5 running C:\Program Files 
>>>>>>> (x86)\BSF4ooRexx\BSF.CLS line 2644: System
>>>>>>>                 resources exhausted." || "0A"x || "Error 5.0: message 
>>>>>>> n/a]."] [PACKAGE] =[a
>>>>>>>                 Package id#_-2109388833] [POSITION] =[25] [PROGRAM]
>>>>>>>                 =[F:\tmp\orx\kirisits\20170425\SAX_noAlerts.rxj] 
>>>>>>> [PROPAGATED] =[1] [RC]
>>>>>>>                 =[40] [STACKFRAMES]=[a List (4 items) id#_-1467321073] 
>>>>>>> [ *-* Compiled
>>>>>>>                 routine "BSF". id#_-1939043649] [ 1811 *-* res=BSF( 
>>>>>>> "invoke",
>>>>>>>                 "com.sun.org.apache.xerces.int
>>>>>>>                 
>>>>>>> <http://com.sun.org.apache.xerces.int>ernal.parsers.SAXParser@117ae12",
>>>>>>>                 "PARSE" , a.1 ) id#_-1938526417] [ 1813 *-* interpret 
>>>>>>> code ")" -- execute
>>>>>>>                 this dynamically created Rexx string id#_-1937397361] [ 
>>>>>>> 25 *-*
>>>>>>>                 parser~parse(XMLFile) id#_-1936143753] [TRACEBACK] =[a 
>>>>>>> List (4 items)
>>>>>>>                 id#_-1458379065] [ *-* Compiled routine "BSF".] [ 1811 
>>>>>>> *-* res=BSF(
>>>>>>>                 "invoke", "com.sun.org.apache.xerces.int
>>>>>>>                 
>>>>>>> <http://com.sun.org.apache.xerces.int>ernal.parsers.SAXParser@117ae12",
>>>>>>>                 "PARSE" , a.1 )] [ 1813 *-* interpret code ")" -- 
>>>>>>> execute this dynamically
>>>>>>>                 created Rexx string] [ 25 *-* parser~parse(XMLFile)] ---
>>>>>>>                 The traceback points to the invocation of the SAX 
>>>>>>> parser from Rexx which
>>>>>>>                 only returns upon completion of the Java parse method, 
>>>>>>> or in this case when
>>>>>>>                 an error interrupts the program. --- So now my 
>>>>>>> question/request: how to
>>>>>>>                 debug this problem/error? How can I get more 
>>>>>>> information from the ooRexx
>>>>>>>                 interpreter? How can one determine what kind of "system 
>>>>>>> resources" got
>>>>>>>                 exhausted and what the cause would be? Can one e.g. 
>>>>>>> determine how many Rexx
>>>>>>>                 objects there are and how many are dead, in the need of 
>>>>>>> getting garbage
>>>>>>>                 collected? In this case whenever (on each SAX callback) 
>>>>>>> the Java side
>>>>>>>                 invokes the native code which then sends the message to 
>>>>>>> the Rexx object
>>>>>>>                 there will be an AttachThread() followed by a 
>>>>>>> DetachThread(). Please advise!
>>>>>>>                 ---rony 
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Oorexx-devel mailing list
Oorexx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/oorexx-devel

Reply via email to