Is it possible to preload JVM to make starting of little one-shot java applications faster?

7

1

Expected algorithm:

  1. You start JVM without actual application (only telling it to load some jars), it loads and listens a socket and waits in a background.
  2. When you start the application (preloaded_java -cp /usr/share/java/....jar:. qqq.jar) it connects to the existing loaded JVM, loads additional jars (if any) and executes main class.
  3. preloaded_java just routes input and output and handles interrupts etc.

Update Implemented a proof of concept: http://vi-server.org/vi/code/prejvm/

$ clojure prejvm.clj&
[1] 2883
$ nc 127.0.0.1 7711 <<< '{"mainclass" "test.Hello"}'
$ nc 127.0.0.1 7712
java.lang.ClassNotFoundException: test.Hello
    at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
    ...
    at clojure.main.main(main.java:37)

$ nc 127.0.0.1 7711 <<< '{"classpaths" ["file:///home/vi/code/prejvm/"], "mainclass" "test.Hello"}'    
$ nc 127.0.0.1 7712
Hello, world; number of args is 0
qwe q e32e qda
qwe q e32e qda

$ nc 127.0.0.1 7711 <<< '{"classpaths" ["file:///home/vi/code/prejvm/"], "mainclass" "test.Hello", "argv" ["qqq" "www" "eee"]}'
$ nc 127.0.0.1 7712    
Hello, world; number of args is 3
sdfasdfasf df sad
sdfasdfasf df sad

Update 2: Found answer myself: Nailgun server (from VimClojure).

Vi.

Posted 2010-09-14T21:26:55.123

Reputation: 13 705

Answers

3

Use Nailgun Server:

Start it:

java -classpath /usr/share/java/clojure.jar:/usr/share/java/clojure-contrib.jar com.martiansoftware.nailgun.NGServer 127.0.0.1

Use it:

$ ng clojure.main 
Clojure 1.2.0
user=>

$ ng test.Hello sdf sdf sdf
Hello, world; number of args is 3
sdfsdf
sdfsdf

It can be obtained with VimClojure: http://www.vim.org/scripts/script.php?script_id=2501

Vi.

Posted 2010-09-14T21:26:55.123

Reputation: 13 705

A quick perusal does not reveal any class loader tricks, so a class will only be initialized once per server run, and not "per use". This may or may not have an effect on the correctness of whatever you are running under NailGun. – Ken – 2010-09-18T00:48:12.333

If some code fails on NailGun because of this then it is probably not well-written. In a good program "initialized once per server run" should just mean that it would be even more fast. – Vi. – 2010-09-18T17:26:35.333

0

No, what you describe is not possible, at least not with the Sun JVM, simply because it's not implemented (though it's a nice idea).

However, if you just run the app once, the OS will cache the data in RAM that was loaded from disk, so subsequent starts should be a lot faster. That might already help.

If you need a higher speedup: Can you maybe change the app, such that it just keeps running and accepts new input?

sleske

Posted 2010-09-14T21:26:55.123

Reputation: 19 887

I want more-or-less universal approach. Looks like the most complex part for it will be "pseudo-java runner" that read arguments and connects to the java daemon. – Vi. – 2010-09-14T23:11:29.787

"... is not possible, at least not with the Sun JVM" Why it can't be third-party application? All necessary features are already present in JVM: our app can load class and execute main (redirecting System.{in,out,err}) somehow. – Vi. – 2010-09-14T23:14:23.367

It's odd that Sun (/Oracle) doesn't do this, since it's been a feature of several "server" JVMs since 1998 or so. – Daniel R Hicks – 2013-11-24T02:01:50.063

0

Sure it can be done. What you describe is actually pretty close to how a Java EE application server works.

jlliagre

Posted 2010-09-14T21:26:55.123

Reputation: 12 469

So it should be like Java application server for console programs. – Vi. – 2010-09-15T10:19:42.963