2

I have a JavaFX application, when the user closes the window, I want to destroy all of the JavaFX related resources and only have a tray icon, where the user can then reopen the application.

I have many background threads running, which should stay running when the GUI is closed. I have tried using Platform.exit() however it has no impact on the RAM usage of the program.

What is the best way to accomplish this? My goal is to reduce the impact on the system from my program as much as possible when the application is closed, but still running all of the background threads.

UrsinusTheStrong
  • 1,239
  • 1
  • 16
  • 33
nsmith95
  • 51
  • 7
  • Things that popup in my mind are classunloading and making sure that there is no link or refference to the javafx application related objects. You could also try to figure out if your bavkground threads are causing the memory usage instead of javafx itself – n247s May 13 '16 at 17:53
  • Class unloading? I have not heard the term before. And I have gone through and nulled any reference to any javafx related object. All stages, controllers, and scenes. – nsmith95 May 13 '16 at 17:54
  • This post discusses it more in detail. It is tricky todo for javafx, but not impossible. Though I would make sure first that your other threads are not the problem. :http://stackoverflow.com/questions/148681/unloading-classes-in-java – n247s May 13 '16 at 18:02
  • 1
    Are you absolutely sure the GUI stuff is what you need to clean up? You should use some sort of performance analysis tool to figure out what's hogging the system's resources. – npace May 13 '16 at 18:52
  • at best, you're going to hog a few MB's of memory. your logic code (in your threads) will probably consume far more. in any event, unless you're processing HUGE amounts of data, your entire app is probably not a significant amount of resources being used. What is it you're seeing specifically that concerns you? Are you eating up 1GB of ram or something? – SnakeDoc May 13 '16 at 20:04
  • If `Platform.exit()` had no impact, then you already know the issue is not the JavaFX code. `Platform.exit()` exits the JavaFX platform and shuts down all of it's threads, etc. All that will be left running is your other non javafx code. – SnakeDoc May 13 '16 at 20:06
  • Right now its sitting at like 300mb of memory when the user is not interacting with it. Another problem I am having is that as the user navigates through, the used memory continues to increase and will not get garbage collected. Is this a problem on my part? – nsmith95 May 13 '16 at 20:17
  • I would recommend using a Profiler. It will help pinpoint where problems might be. It's sounding like your data structure is your issue. I assume as users navigate, you display data in different ways or different data... probably have a leak someplace that's holding a reference and preventing GC. JProfiler is one of the best profilers I've used, but it's expensive. A free profiler is baked into the Oracle JDK, called VisualVM, and is you're using the Oracle JDK, you'll already have it installed. Use it to examine the memory of your app. – SnakeDoc May 13 '16 at 20:45
  • Another thing to consider is that GC may not feel a need to actually garbage collect. Depending on how much memory your startup parameters allow, you may not be getting to a point where it's necessary. Java is a memory managed language, so the GC does it's thing when it feels it needs to. Usually, as a Java developer, you don't really need to worry about this stuff. Have you run out of memory and your app crashed? It could be that you're pre-optimizing something that's not a real issue. – SnakeDoc May 13 '16 at 20:48
  • there is no one or two lines of code to properly clear up resources, as you were trying to go with `Platform.exit()`, i guess. – Elltz May 13 '16 at 23:40

1 Answers1

1

One option is to run the application as a separate process, launching the process when you want to create the application and exiting the process when the application is no longer needed (so completing a full application lifecycle). That way you will be absolutely sure that the application is not consuming any resources when it is not being used, because it won't be running.

How you would accomplish the launching and any communication between your tray service and the application would be up to you. You can research various mechanisms and, if you decide to go this route, ask some new follow up questions on accomplishing certain aspects of the task.

Some example routes you could look at are the ProcessBuilder, which is admittedly a pretty finicky and horrible API or the new Process API updates that will be available with Java 9. If wish to ensure at most a single instance of the application process is ever used, there are solutions for that. If you need to send a signal to the running application process, you could use something like RMI or run a basic HTTP REST server in your application and send messages into that.

As an aside, years ago there used to be some ongoing work on building multi-process JVMs, but there was never any wide uptake of the idea for Java. Though most modern browser clients, such as Chrome and Firefox, are multi-process architectures, the linked articles give some insight into this architecture, some of the potential implications of it and why it used for those applications.

Before going such a route, I would advise you to ensure that such an approach is truly necessary for your application (as pointed out by user npace in comments).

Community
  • 1
  • 1
jewelsea
  • 150,031
  • 14
  • 366
  • 406