Jython / jvm garbage collector question

In jython, consider the following code:

timer = None

@when("some trigger")
def myrule(event):
   global timer
   timer = ScriptExecution.createTimer(......)

My understanding is that ScriptExecution.createTimer() will create a timer object which will get stored by the timer global variable.

I understand that once the timer has executed, the timer object remains in memory, and because it was assigned to a variable, i.e. something is referring to that timer object, is it true that the Garbage Collector (is it Python’s GC or JVM’s GC?) will not touch it, until such time when the script is reloaded (which invalidates the reference)?

If that were the case, is it true that the only way to make the GC “collect” / free up the memory that is allocated to the timer object, or remove the timer object itself, is by removing all references to it, i.e. do this somewhere:

timer = None

I’m not a developer, but wouldn’t timer.cancal() also cause timer to eventually be garbage collected?

afaik, timer.cancel() would not. cancel() is just a method of the object, just like timer.reschedule(), hasTerminated() etc.

This is what timer.cancel() does:

    public boolean cancel() {
        cancelled = true;
        return future.cancel(true);

It doesn’t alter the object’s reference count or anything related to GC.

In Rules DSL, you have to cancel timers else they remain in memory until they expire (which they don’t do in time if you gave a bad expiry value).
In Jython, I’d believe you have to do that as well. Assigning null will likely create a memleak.

I’m talking about timer objects that have terminated. Cancelling it makes no sense and would have no effect whatsoever to the GC.

I don’t see how assigning the returned timer variable to Null / None could possibly create a memleak. This is not C. Quite the contrary, my understanding, is that assigning it to null releases the reference and allows the GC to claim / free the memory.

cancel() cancels the timer, that is, to stop the scheduled timer from executing, and once again as far as I can see, has nothing to do with GC.

Well I can’t answer that and doubt anyone can. JVM will handle that one way or the other. I believe it’ll handle “assigned” code just like any other, i.e. it’s subject to the usual GC procedures that you can read up in Java docs or forums. I think in mixed-mode (JIT to apply) it’ll drop compiled code when that has not been used in a while, so when you access that again much later on (say on timer expiry), it needs to recompile, eventually resulting in delays.
Frankly I don’t know. But I think it’s of no importance in terms of openHAB memory use.
Generally speaking, Java 11 seems to perform better there than Java 8 does.

It’s of importance to me, hence why I’m asking to see if anyone might be familiar enough with JVM / jython (seeing that jython is python, which is a GC’ed language, running atop of JVM which is also a GC’ed language).

It sounds extremely wrong to me if the GC would unload/invalidate/free up an object / memory that is still being referenced, just because it has not been accessed in “a while” (whether that is a day, a week, a month, or even a hundred years).

In a normal scenario this may not matter because when a script is reloaded (e.g. edited), everything it created would be invalidated (except timer objects would remain active!).

However, I am asking this because I am working with variables inside modules that can be accessed by multiple scripts. Furthermore, I am deliberately making it so scripts will not be able to reload the module (thus invalidating the variables within the module). So in short, it matters to me.

Frankly I don’t understand your issue, sounds academic to me. But ok I understand you feel it matters.
But I believe this is a variant of the XY problem: what’s the point as you cannot change anything about the way JVM handles that anyway ? BTW there’s probably no simple answer as I’d think it also depends a lot on the Java you use and its options.
If it does not GC them, you have no problem. If it GCs them, it doesn’t delete values just compiled code.
On next use there’s a delay due to recompilation. So just provide enough memory.
Btw that’s where Java 11 improves over Java 8 because of the change in GC algorithm.
So if your real problem is processing delays or fear of those, try going Java 11 and you’re probably set.

I think you’re missing my point / question completely, but thanks for trying to help.