views:

161

answers:

7

EDIT I don't want to use Java Web Start

I've got a Java application that I'd like to run with different VM parameters depending on the amount of memory the system it is launched on has.

For example if the machine has 1 GB of memory or less I'd like to pass "-Xmx200m" and "-Xmx400m" if it has 2 GB and "-Xmx800m" if it has 8 GB (these are just examples).

Is there a portable way to do this?

I've tried having a first tiny Java app (hence portable) that determines the amount of memory available and then launches a new Java app but I don't think this is very clean.

As of now I've written Bash shell scripts that invoke the Java app with the correct parameters depending on the config but it only works on Linux on OS X.

What is the correct way to solve this?

Would application packager package ;) help ?

A: 

To define the various launch configurations I would go with JNLP. xmx can be specified there.

Unfortunately this still leaves you the task of finding out how much memory the system has, for which your tiny Java app sounds best.

Christopher Oezbek
A: 

In the same line as your existing solution, I use scripts to launch my applications but instead of Bash I use Python. Python ships on most Linux distros as well as OSX. The only difficulty is Windows, but you can suggest Python as a prerequisite similar to getting the JVM installed.

basszero
@basszero: +1... I don't know who modded you down (I modded you +1, so back to zero :) I know that Python is officially on OS X (I use it for a few thing ;) To all: scripting before launching an app is *very* common and most Java installers do just that (like izpack etc.).
LowLevelAbstraction
adding additional moving parts adds unnecessary complexity.
Pat
ant isn't an additional moving part?
basszero
Ant runs on Java, which users will need anyway.
Bart van Heukelom
additionally Ant can be bundled within the original java program as another .jar so no change in deployment.
Pat
+2  A: 

Are you sure you want to do this? In general, Java application need a certain amount of memory, not more, not less.

If you have a machine with little memory and you specify a small number at -Xmx you risk to run out of memory.

If you have a machine with lots of memory and you specify a large number the application won't use all the memory but only the amount required by the objects in use.

So, in general, you don't lose memory by specifying large numbers at -Xmx.

(Exceptions are server applications which have a large amount of object 'throughput' and tend to waste memory.)

Wolfgang
Yes, I am sure I want to do this. There's a reason, why, for example, Photoshop will use more memory when it's on a machine that has 20 GB of ram and the user expects the app to use more memory in Photoshop's case (and in my case). "In general" is not "in Photoshop"'s case nor in the case that prompted me to ask this question :) There are *countless* types of applications where using more memory on systems that have, well, more memory, makes sense. Mine happens to be one of them.
LowLevelAbstraction
The -Xmx parameter doesn't configure how much memory your application should use but how much it is allowed to use. How much it actually uses depends on your application logic (how many objects it creates). The only effect making -Xmx depending on the machines's available memory is getting OutOfMemoryError on small machines but it will not make the application use more memory on large machines.
Wolfgang
@Wolfgang: you insist on not getting it. To be exhaustive, I set up both -Xms and -Xmx but thanks for your pedantry. The *whole* point of setting an -Xmx smaller on a small machine is to not get an OOM. Oh, btw, at runtime my application adapts itself to the amount of memory available. A concept which you're obviously not familiar with. And **YES, I DO REALLY WANT TO DO THIS**. What don't you understand in the **QUESTION**? If you can't answer, then please use comments, not an answer.
LowLevelAbstraction
"The whole point of setting an -Xmx smaller on a small machine is to not get an OOM." This is not necessarily right. -Xmx will override the default value the JVM uses (which is JVM-dependent). If your -Xmx is smaller than the default, you actually make an OOM more likely (but you might want to do it if you want to avoid problems with memory leaks).
sleske
+2  A: 

What's your gripe with your current approach, exactly? It's completely portable (unlike various scripting solutions... why is a script "cleaner" than 100%-portable bytecode?), and it'll adapt perfectly if the hardware changes after installation (so it's better than capturing the hardware details as part of your installation script).

If you can explain the actual issues it may be easier to come up with a solution to those specific problems.

Here's an alternative that you might like better, actually: copy what Photoshop, GIMP, etc. do and make "resource usage" or "performance" part of the preferences for your app. You'll have to prompt them restart your app when/if they change this setting (to relaunch your app using the modified start procedure, since you can't change the memory limits for a running app... where you write the new flags is deployment-method dependent), but that's not such a disaster for a setting they'll likely change exactly once.

You could also check their hardware on first run, and if your default installed setting is way off from their setup, prompt them to change the setting then.

Rob Whelan
+2  A: 

Since http://ant.apache.org :

  1. is a java program
  2. has built-in forking/launch mechanism
  3. has scripting basics
  4. is embeddable within another program
  5. has command line parsing and other basic stuff that deals with environment/config issues.

I suggest that you

  1. Create a build.xml (or create the targets/tasks programatically)
  2. and have the your initial program be ant running the build.xml script
Pat
+1 Using Ant as part of the product, how creative
Bart van Heukelom
Thanks! For the praise :-)
Pat
@Pat: +1, I'll look into it. Sounds interesting.
LowLevelAbstraction
A: 

For any 'configuration task' I would suggest to use izpack, really powerfull and free packager. You might also take a look at eclipse, where they have implemented restarting a java application.

rocker
A: 

Using a bash script instead of a JavaApplicationStub in the application bundle allows for changing the parameters. However, this breaks the handleOpenFile() functionality: the event signal never arrives at the handleOpenFile ApplicationEvent event. See http://lists.apple.com/archives/java-dev/2010/Jun/msg00009.html

Andreas Schwab