Two types of errors

I wanted to run Datomic Pro on a cheap test server with 1GB RAM. The default settings for Datomic Pro are a bit too memory-intensive for this. This is a tale of two very similar errors that I had and how I fixed them. What's interesting is the difference between the two.

Let's say we have followed the official documentation, started the transactor with the dev template and the datomic console. When we now start the repl with official bin/repl we get the following error

Error occurred during initialization of VM
Could not reserve enough space for object heap

If you haven't seen this type of problem, google is probably your first resource. Eventually you'll find a line that you can paste in your terminal and be done with it.

Another - arguably more robust - approach is to realize that the error is about a specific resource. If we run htop or a similar program we can see the memory usage is through the roof, and that might lead you to the question: why is java taking up so much memory? you are barely doing anything! Googling for this problem - or, even better `man java | grep memory` - will eventually lead you to a page with something like the following settings

export JAVA_OPTS = "-Xms512m -Xmx512m"

These are the minimum and maximum memory settings for the JVM. Make sure to run it in all your relevant terminal sessions. Why 512m? Because it's a nice round number and half of whatever the comment in the transactor dev-template file suggest.

This is all well and good. However, if you try to run bin/repl again you get the same error again! You could try halving the number again, but before you do that you might want to open the box and see what you are actually running. This is bin/repl
cd `dirname $0`/..
bin/run -r $@
Looks like the meat is in bin/run. Let's see what that looks like
cd `dirname $0`/..

while [ $# -gt 0 ]
    case "$1" in
            java_opts="${java_opts} $1"
            clojure_args="${clojure_args} $1"

/usr/bin/env java -server -Xmx1g -Xms1g $DATOMIC_JAVA_OPTS ${java_opts} -cp `bin/classpath` clojure.main -i "bin/bridge.clj" ${clojure_args}
Curly brackets in bash are indicative of expansion (if you don't know this, you would quickly find this out via google), and you can also see that there's some kind of special case-by-case handling depending on what parameters you pass into bin/run. You are calling bin/run via bin/repl so it doesn't seem to be relevant to the problem. You might see that there's another environment variable called $DATOMIC_JAVA_OPTS rather than the default $JAVA_OPTS. Looks promising, and if you set it like above you'll notice that the repl will start, and you will be able to connect to the dev database.

Here's the kicker: you probably wouldn't have found the second problem by googling. Unlike the first problem, this is specific to the bash files that Datomic runs on. If you know more about the JVM or system administration you might've had figured it out another way.

The first type of problem is the generic, googleable one. The second is the specific one. To solve that you have to actually debug the error and figure out where exactly your model of the problem isn't matching the reality. Many man-hours have been wasted by people confusing the specific for the generic, cursing at the screen "this should work!". If you have a specific problem, few things beat opening up the box to see what you are actually doing.

PS It's entirely possible that I've misunderstood something about bash/JVM/sysadmin and that there's a better, simpler and more correct way to do this. Let me know in the comments! DS