Subscribe
Hello "Todd Coram" :-) You are now subscribed -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
PilBox & Java object lifecycle
Hi, I have a long running PilBox Android app that tends to just "crash" (with a "Webpage not Available... net:ERR_CONNECTION_REFUSED") after running for a few hours. At this point, the REPL is unresponsive at this point and nothing is in the PilBox log file. My app makes heavy use of Java calls (dozens every 5 seconds) and this got me wondering about how PilBox treats the Java object life-cycle. I don't see clearly how the Java objects themselves are referenced so as not to be collected by the Java GC. I do see a static HashMap in InOut.java. Are Java objects "put" there to save them from the GC? If so, when are they removed from the HashMap? I don't see any "remove" in InOut.java or other PilBox Java sources. If objects are referenced there Is it possible that these objects are never freed? /todd -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: PilBox & Java object lifecycle
I should be a little clearer: I "instantiate" dozens Java object every 5 seconds and wonder how Pilbox affects their life-cycle /todd On Thu, Aug 24, 2023, at 12:42 PM, Todd Coram wrote: > Hi, > I have a long running PilBox Android app that tends to just "crash" > (with a "Webpage not Available... net:ERR_CONNECTION_REFUSED") after > running for a few hours. At this point, the REPL is unresponsive at > this point and nothing is in the PilBox log file. > > My app makes heavy use of Java calls (dozens every 5 seconds) and > this got me wondering about how PilBox treats the Java object > life-cycle. > > I don't see clearly how the Java objects themselves are referenced so > as not to be collected by the Java GC. I do see a static HashMap in > InOut.java. Are Java objects "put" there to save them from the GC? If > so, when are they removed from the HashMap? I don't see any "remove" > in InOut.java or other PilBox Java sources. > > If objects are referenced there Is it possible that these objects are > never freed? > > /todd > > -- > UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: PilBox & Java object lifecycle
Hi Todd, > I have a long running PilBox Android app that tends to just "crash" (with a > "Webpage not Available... net:ERR_CONNECTION_REFUSED") after running for a few > hours. At this point, the REPL is unresponsive at this point and nothing is in > the PilBox log file. I need PilBox open all day for various reasons, and monitor it constantly. So I notice quickly if something goes wrong. In fact it crashes sometimes, but it is usually longer than a few hours (more like about once or twice a week). Typical crashes are usually not PilBox's fault. Android is a nasty host system, it kills apps whenever it feels it needs memory (kills with -9, not -15 !!!). Other situations are when Android updates system components in the background (most notably the System WebView), then PilBox is also killed. But: In most of the above cases, there is no connection error, but PilBox "resets", i.e. it goes to the home screen and lost its context. Technically, this means a new instance of the internal PicoLisp process was started. If you see the above connection errors, it seems that the PicoLisp process is gone and not restarted. Not sure. Also you probably know that you can force a full stop of PilBox and PicoLisp by swiping it off. This stopping did not work reliable in older PilBoxes and was improved a few months ago. BTW, do you use a current version of PilBox? Latest official release was 23.7.13 (183) > My app makes heavy use of Java calls (dozens every 5 seconds) and this got me > wondering about how PilBox treats the Java object life-cycle. A valid question. > I don't see clearly how the Java objects themselves are referenced so as not > to > be collected by the Java GC. I do see a static HashMap in InOut.java. Are Java > objects "put" there to save them from the GC? Yes, this is exactly the reason. > If so, when are they removed from the HashMap? I don't see any "remove" in > InOut.java or other PilBox Java sources. > > If objects are referenced there Is it possible that these objects are never > freed? > ... 2nd mail > I should be a little clearer: I "instantiate" dozens Java object every 5 > seconds > and wonder how Pilbox affects their life-cycle I understand the question well. And was aware of the trade offs from early on. The objects in the hash map are indeed never removed. This would be difficult to implement, because the Java side has no information about which objects are still in use on the Lisp side. Is this is really the cause of the problem? Most java calls do not make a new object each time, and stored in the hash map are not all involved objects, but only those which are reflected back to Lisp (and not all created internally). And: The objects in the hash map are truly minimal. They have no local data, they are just stubs. They seem big when looked at with (show Obj), but all these data are generated on the fly via reflection and not part of the objects themselves. Still, you are right that this mechanism will use more and more memory. Have you checked it? I did occasionally, using something like this code in the REPL: (let R (java "java.lang.Runtime" 'getRuntime) (java R 'gc) (let (Fmt (-7 9) Mem (java R 'totalMemory) Free (java R 'freeMemory) ) (tab Fmt "Total" (format Mem 3 "." ",")) (tab Fmt "Free" (format Free 3 "." ",")) (tab Fmt "Used" (format (- Mem Free) 3 "." ",")) ) R ) Perhaps we can come up with ideas how to improve the situation. ☺/ A!ex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe
Re: PilBox & Java object lifecycle
Hi Alex, Fantastic language (Picolisp) and very, very useful port to Android. On Thu, Aug 24, 2023, at 2:15 PM, Alexander Burger wrote: > Is this is really the cause of the problem? Most java calls do not make a new > object each time, and stored in the hash map are not all involved objects, but > only those which are reflected back to Lisp (and not all created internally). TBH, most of my troubles came from using the Android JSON library (which requires me to explicitly create the Java objects to add) and I do plan to move to a pure Picolisp implementation. But it did get me thinking about everywhere I instantiate a Java object via (java "classname" T). > The objects in the hash map are indeed never removed. This would be difficult > to > implement, because the Java side has no information about which objects are > still in use on the Lisp side. I'm pushing PilBox to the limits of (probably) what you intended: I want to run a minimal UI background service that scans BLE. It works well, but I'd like to keep track of the Java objects, even if done explicitly. With that said, there are occasionally instantiated objects I'd like to keep track of and don't mind house cleaning. I could even imagine instrumenting something handled in catch clauses or loop/function exit situations. I just need access to that hashtable. > Perhaps we can come up with ideas how to improve the situation. > Perhaps something like: (java NIL 'obj) for removing it from the hashtable? The "complex management" of this could then be handled in pure Picolisp... Would it be as simple as something like (in Reflector.java reflect()): if (y == InOut.Nil) { // Release reference to Object Object o = lst[1]; // object to release int idx = o.hashCode(); InOut.Obj.remove(idx); Io.Out.write(InOut.NIX); Io.Out.write(InOut.NIX); x = null; Or am I heading in the wrong direction? /todd -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe