Please see attached patch that implements lazy ByteCode loading for against MAIN 0.98 patch (from source downloaded on Sept 4, 2013).
I'm using the modified version just in a regular java -jar MyJar.jar situation so I'm not sure if the changes will break anything else, but it seems to work pretty good so far.
JVM Memory usage after a gc() went down from:
56MB using (0.96) down to 18MB using the modified 0.98 version.
This was with preloading bytecode for classes in the main/main.jar and one my other /lib/ jars, other bytecode was lazy loaded.
I've tried to make it flexible so there are new -Done-jar property options to:
- Disable preloading the main jar (on by default)
- Allow preloading resource bytecode eg. non-classes (off by default)
- Pass a comma seperated list of jars to preload.
- Disable lazy loading so that it acts similar to the old version.
By default it also loads byte[] for ByteCode into a SoftReference map for use later on startup, these bytes however aren't guaranteed to stick around if the garbage collector is run. If referenced byte[] still exists in memory then the lazy loaded ByteCode will utilize them to avoid a jar inputstream lookup.
It will also attempt to fill the SoftReference map with other entries that are not yet loaded into ByteCode upon a lazy load request for a class / resource from that codebase jar.
(this might happen if tight memory constraints cause the byte[] in some SoftReferences to be garbage collected)
I hope it helps!
Cheers,
Jamie
I realized that resources were being loaded by jarfile connections instead of directly from the onejar: handler and ByteCode handling.
I've fixed this issue and attached an additional patch that you can apply after the first one.
There's also a fix in there to hard-code the URL handler for URL generation if the onejar Handler cannot be found by the URL class. eg if the one-jar.jar is not on the system classpath. This was a problem for me because my Launcher.jar downloads and invokes the one-jar packaged jar directly.
Thanks,
Jamie