views:

134

answers:

3

Java loads the resources as they are needed. This make my tiny small desktop application to be very slow when opening a window.

How can I do to load all the resources when starting the app? Is something related to classloaders?

EDIT: does this code work if the files are inside a jar?

EDIT2: Note that the aim is not to reduce the startup time, but to reduce the time of new windows opening after the app is started. I want all resources to go to the memory and stay "ready for use", so after loaded the app will run faster the user's commands.

A: 

The problem is harder: The code is initialized if it is used, which can be seen even on the method level. So you have to run it to load it.

The only other possibility is to buy Excelsior Jet, which does the compile step for you (and returns a nice .exe as a side effect).

EDIT: You can reduce your runtime by Class.forName()ing all your classes during startup, and having everything loaded when its needed. Please note that for having everything really fast, the code must have been run, so maybe you can open, but hidden, all windows, the close them, and then really show the main window from which all other windows are opened. Sadly this will make your app startup really slow. But it can even be done in background, while the user decides what to do next.

Daniel
is there a way to iterate over all classes without explicit writing their names?
Tom Brito
please, see my edit to the question
Tom Brito
the aim is not to reduce the startup time, please see my 2nd update
Tom Brito
I understood. See edit.
Daniel
A: 

If you mean also other resources than classfiles then you could use the proxy pattern to delay loading (lazy loading) until you really need the resources.

stacker
I want to do exactly the opposite, load all resources at startup, so they are available in memory for fast access when I need them.
Tom Brito
+1  A: 

Java loads the resources as they are needed.

Actually, it is more complicated than that. If you have a class A that statically depends on a class B that statically depends on a class C, then loading A will trigger eager loading of B and C and so on. But some libraries (and I think AWT and Swing do this) internally use the Class.forName(...) method to lazily load implementation classes. This reduces the number of classes that are loaded initially, and (ideally) avoids loading code that your application will never use.

How can I do to load all the resources when starting the app?

I suppose that you could create explicit static dependencies to defeat the laziness above, but that probably won't make your application's initial window appear more quickly. A better strategy would be to try to use more lazy loading to reduce the amount of code that needs to be loaded to get the initial window visible. But this needs to be done judiciously. If you lazyily load classes that are needed for the initial window, you may actually make startup slower.

Compiling to native code (using GCJ for example) is another alternative, but this has various downsides; e.g. larger binaries, more native library dependencies, portability issues, (possibly) slower execution speed for a long running application.

Re your EDIT: I think that code will "work", but I don't see how it could possibly speed up your application's startup.

Stephen C
"A better strategy would be to try to use more lazy loading to reduce the amount of code that needs to be loaded to get the initial window visible". Actually, I don't care about the initial window slow to show, what I care is that after shown, all other windows need to be ready to show in a fast way. I want all resource loaded in memory for fast access when the application is started. (it will not run out of memory, becouse is a small app).
Tom Brito
Have you asked your users? Is that what they think too? Anyway - if you think that is the right thing to do, add the static dependencies as I suggested.
Stephen C
@Stephen I saw they using it, and it's no problem waiting the app to load. But is a big headache after the app is loaded wait for every click you give.. ;)
Tom Brito
I think i do not understand well.. using the Class.forName() will reduce the number of classes that are loaded initially? Because what I want is to load all classes/resources while showing the splash screen.
Tom Brito
In the first paragraph of my answer I explained how static dependencies cause the classes to be loaded eagerly. Then wrote *"I suppose that you could create explicit static dependencies to defeat the laziness above ..."*. Is that clear now?
Stephen C