I maintain a large Mathematica package (here) that, for certain operations, calls out to a Java library (here). The details of the libraries are not important, but I've come across a frustration with JLink that I can't seem to find a clean solution to.

When the Mathematica library is loaded, it automatically locates the Java library (which is embedded in the directory structure of the Mathematica library) and makes sure that the appropriate classes get loaded. However, when these classes get instantiated by the user, Java throws an out-of-memory error. This is correct; the Java library requires slightly more memory than Mathematica initially instructs the JVM to use as its max (I've found that using "-Xmx512M" is sufficient to avoid exceptions). It's easy enough for me to edit the java command line options as spelled out in the answer to this question, but this requires doing some work every time I load the library. I can put these instructions in my init.m, but this doesn't work for anyone who just downloaded the library. Note that, as the library is intended primarily for neuroscientists, it cannot be assumed that whoever is using the library has more than passing familiarity with Mathematica or Java (Matlab and Python are by far the default languages in neuroscience).

Accordingly, I'm stuck with a conundrum: how to initialize the library in such a way that it functions correctly without requiring backflips of the user. Some possible solutions I've considered:

  • Go ahead and call ReinstallJava[] when the library is loaded; this will screw up any existing JLink connections, however
  • Catch out-of-memory exceptions in my Mathematica code and translate them into Mathematica messages that explain to the user that they need to add more memory to the JVM; this is hard, as it requires me to wrap up every point of interface with the java library, however, and introduces more complexity to the user than I'd like. Additionally, after reinstalling java, the library must be re-initialized in order to make sure the class path is correct and the java classes are all loaded.
  • Detect, on initialization, that Java has insufficient memory and print a warning message; similar problems as above, and I'm not familiar with a way to query the JVM max memory from within Mathematica (though it seems like it should be possible)
  • Include an installation function in the library that, when run, edits the user's init.m file to change the default JVMArguments; this seems like a hack, and complicates the library's installation, but might be the best option I've come up with.

My question: none of the above solutions feel remotely elegant; is there a better way of doing this? If not, is there a way to query the JVM max memory via Mathematica or an interface for editing the user's Mathematica initialization? Or, is there a way to open a separate 'private' JLink connection for use by this library alone, in which I can specify the memory limit myself?

  • $\begingroup$ For those interested, I went ahead and coded up a combination of the third and fourth bullet points above into the Mathematica library linked early in the post. Specifically, see the end of the src/Neurotica.m file, the section marked by the "#JLink Maintenance" comment line. I would be interested in any suggestions regarding either the above post or the solution implemented in the library. $\endgroup$ – nben Feb 20 '16 at 20:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.