Open AlexIvchenko opened 2 weeks ago
I checked the usage of importedObjects
in the current code base and in the original version from 2017.
In both cases, importedObjects
is used for writing and for look-ups - it was and is never cleaned.
The purpose of this Map
is to maintain references of remote objects. Remote objects are objects which are fetched through DBus and represent the state of a remote application.
This ensures that if querying for the same object (using the object path) on DBus you will receive the same object instead of creating a new one. This also means, that if you have one connection and use that connection in different parts of your application, you will always get the same object.
The Map
is part of the current connection. As soon as the connection is closed (by your application or by the remote end) the Map
and anything related to the actual connection is eligible for garbage collection.
I'm not sure that using a WeakHashMap
in place of a regular Map
is a suitable solution.
A WeakHashMap
would allow the GC to remove remote objects which are currently not reachable. This would cause remote objects to get lost also if the application will access it from somewhere else later.
It may introduce other problems I'm not aware of of yet.
I use dbus-java to manipulate systemd units using https://github.com/thjomnx/java-systemd (https://www.freedesktop.org/wiki/Software/systemd/dbus/). It uses single connection to work with systemd via dbus.
In that scenario the connection keeps obsolete RemoteObject
s for systemd units which are not needed and even not present in systemd anymore.
This would cause remote objects to get lost also if the application will access it from somewhere else later.
Is connection supposed to be reopened periodically to cleanup unnecessary objects?
Is connection supposed to be reopened periodically to cleanup unnecessary objects?
There is nothing to clean up once a DBus connection is closed. At that time everything belonging to that connection is obsolete. This includes the importedObjects
map which is a member of AbstractConnectionBase
which in turn is the base class for all connections of this library (no matter which transport).
I would like to understand what your application is doing so this behavior becomes an issue. If your application connects to Systemd via DBus, does something and then disconnects everything should be fine. If the application keeps the connection for weeks, this may be problematic.
In that scenario the connection keeps obsolete RemoteObjects for systemd units which are not needed and even not present in systemd anymore.
It is impossible to know if an remote object is still valid from the library point of view. You have to do any sort of 'action' with that object and then only you know that it is broken - the library internals are not aware of that.
I would like to understand what your application is doing so this behavior becomes an issue.
Communicating with systemd (starting systemd-units) via single connection for entire lifetime of application. Because of that it may keep connection for long time (basically until we need to update the application).
I updated the code so you can now use WeakHashMap
for imported objects. You can enable that using withImportWeakReferences
on the DBusConnectionBuilder
.
However, the default behavior of using regular (hard) references is unchanged. I may change that in the future, but I'm still unaware of the possible side effects. Nevertheless if you set the flag using the builder your will not be affected by future changes of the default.
Hello!
We used 2019 year forked version of this library and now we are assessing the possibility to upgrade. We encountered that there is a memory leak in
AbstractConnectionBase.importedObjects
because objects is only added/queries to this map, but never removed. I suppose current version is affected by this issue. Our fix included changeConcurrentHashMap
toCollections.synchronizedMap(new WeakHashMap())
, but maybe it not the best option.P.s. thank you for great library)