Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory leak in AbstractConnectionBase#importedObjects #261

Open
AlexIvchenko opened this issue Jul 10, 2024 · 5 comments
Open

Memory leak in AbstractConnectionBase#importedObjects #261

AlexIvchenko opened this issue Jul 10, 2024 · 5 comments

Comments

@AlexIvchenko
Copy link

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 change ConcurrentHashMap to Collections.synchronizedMap(new WeakHashMap()), but maybe it not the best option.

P.s. thank you for great library)

@hypfvieh
Copy link
Owner

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.

@AlexIvchenko
Copy link
Author

AlexIvchenko commented Jul 10, 2024

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 RemoteObjects 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?

@hypfvieh
Copy link
Owner

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.

@AlexIvchenko
Copy link
Author

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).

hypfvieh added a commit that referenced this issue Jul 12, 2024
@hypfvieh
Copy link
Owner

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants