views:

155

answers:

5

We have a Swing app that processes relatively large amounts of data. For instance we currently process csv files with millions of rows of data. For the reasons of performance and simplicity we just keep all of the data in memory. However different users will have different amounts of data they need to process as well as different amounts of RAM. When creating the installer, of course we need to specify the heap size. Is there any easy way to allow the user to specify the heap without them needing to hand edit a configuration or .bat file? I'm guessing not all users would be comfortable with this.

I've seen one example where an app specified three different shortcuts each with a different amount of memory specified. This could work but I would like an option that is more flexible. The user could then just choose the one that would work best for them.

+6  A: 

I recommend having something similar to IntelliJ. It brings up a configuration dialog when an OutOfMemoryException occurs. This dialog allows the user to configure the heap size and stores it to idea.exe.vmoptions. You would need to sub the contents of the file into the java/javaw launch command or have one Java program bootstrap and launch the real one.

A really cool variant on this is to suggest a memory size based on the data size. The user really has no way of knowing how much memory your program needs so any guidance you can provide in selecting the value will help them immensely.

It is extremely important in support of this solution that you expect and handle OutOfMemoryExceptions in a way that avoids data corruption!

Alain O'Dea
A: 

You did not mention how you are creating the installer. If you do not already use it, I suggest using NSIS. The documentation is good and it has a plugin for eclipse. You can use the wizard to generate the nsi file and then edit it manually for the options that are not available with the wizard.

As to your current requirement, simply add a page to the installer for the options and based on the option selected, copy the correct system properties file to the user settings folder that you can use to start your program. I am not sure if its possible but I think once the program is installed, the user can re-run the installer and select a different option.

Nithesh Chandra
We are using NSIS. The problem with this solution is that the heap size is fixed at installation time. The user should be able to change the heap size later when they add more memory to their computer or have to work on a larger file than they have ever worked on before.
Jay Askren
Just ask the user to re-run the installer and choose a different option if they need a bigger heap size. If you want to make it easier for the user, try creating a small program that displays a dialog window to let the select the heap size and launch your main program as a different process. There's a discussion a about it at http://stackoverflow.com/questions/480433/launch-jvm-process-from-a-java-application-use-runtime-exec
Nithesh Chandra
+1  A: 

I would write a short startup.jar with very few fixed memory settings starting from a script. In turn startup.jar will start your target app with Runtime.exec() and adjusted parameters.

You end up in 2 JVM instances that spend more memory than only one JVM. But if your application will spend a lot of memory anyway the first JVM does not matter.

PeterMmm
+1  A: 

The main idea would be this:

  • Launch your main application through a shell script similar to this:
@echo off
setlocal
REM This reads the JVM command line options from a user configuration file
for /f %x in (%HOMEDRIVE%%HOMEPATH%\myapp.config) do set JVM_OPTIONS=%x
REM Important: call javaw and not java
javaw -jar myApp.jar %JVM_OPTIONS%
endlocal
  • In your Swing application, have a menu option Memory settings.... When the user selects that, parse the user's configuration file and populate a settings dialog so that the user can change whatever it is appropiate. When the user clicks Apply or Ok, overwrite the user configuration file with command line options according to the user's selected settigns (in your case, -Xmx), and show a message saying something like Restart the application to apply these settings.
gpeche
@gpeche i like the idea of having a menu in swing application . when you set the memory configuration , we can reload the userdefined classloader, where we have loaded the application.
Suresh S
Reloading the classloader is not enough, I think you need to exit and restart the JVM for the changes to take effect.
gpeche
+1  A: 

catch the outofmemory excpetion , lauch a swing user dialog to set the memory limit, pass this value to a thread that uses Runtime.exec() restart the application using java -cp lib's jar vmoptions that will launch a new jvm with memory size specified to user.sample:

 Runtime.getRuntime().exec("java -cp
 -Xms2560m -Xmx2560m -XX:NewSize=32M -XX:MaxPermSize=256M -XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC -XX:+UseParNewG launch.jar");
Suresh S