0

From the py4j official blog (yes it's an ancient blog), the following quoted sentence doesn't seem to be reasonable to me.

if javaObject is no longer referenced in the Python program, javaObject could be garbage collected before method1() is called.

The author further explains that for a javaObjet.method1() statement, the order of operations could be

  1. get attribute method1()
  2. decrease reference count of javaObject
  3. garbage collect javaObject on Python VM
  4. garbage collect javaObject on Java VM
  5. call method1.__call__() method
  6. call javaObject.method1 on Java VM
  7. Error!!! javaObject no longer exists on the Java VM!

How does javaObject get garbage collected when it is calling the method1?

  • If I get it correctly, the python expression `javaObjet.method1()` will be evaluated as `javaObjet.__getattr__("method1").__call__()`, so when the object returned by `__getattr__` does not keep a reference to the receiver object, it might get garbage collected before `__call__()` is invoked. But this raises the question how `__call__()` gets a reference to the receiver in the first place. – Holger May 06 '19 at 14:48
  • @Holger But why `javaObject` could be garbage collected before `__call__()` is invoked, since the reference `javaObject` is not overwritten and its reference count is 1? The receiver of the `__call__()` method is the `JavaMember` object obtained in `__getattr__` call of `javaObject`, and the `JavaMember` object is alive. – ms huang May 07 '19 at 02:51
  • `javaObject` is just a name. You seem to assume that it has to be a reference that stays valid all the time. But what if it is a field, set to `null` by a different thread. Or if it stands for an expression like `methodReturningAnObject()`. I don’t know how Python handles its local variables, perhaps, it would decrement the count for a local variable as well, if `javaObject.method1()` was the last use of the variable. In Java, which does not use reference counting, a local variable does not prevent the collection at all (but it would never fail due to gc when invoking a method). – Holger May 07 '19 at 06:45
  • @Holger I got it, thanks for your explanation. To recap, the variable reference as a field could be overwritten asynchronously in another thread, or is returned as a temp object and is not used after the `__getattr__` call. In either situation the object is garbage collected. – ms huang May 07 '19 at 07:01
  • Yes, the key point is that the nature of `javaObject` is not discussed, but the fact that `javaObject.method1()` will not hold an additional reference to the object, unless the implementation of `__getattr__("method1")` returns an object explicitly holding a reference to it. – Holger May 07 '19 at 07:07

0 Answers0