Set Scala kernel JVM max heap size based on the environment variables
See original GitHub issueI am running my Jupyterhub in a Docker container on Kubernetes. The Almond kernel starts as JVM process in that container. The process call for the kernel looks like following there
java -jar /root/.local/share/jupyter/kernels/scala/launcher.jar --connection-file /root/.local/share/jupyter/runtime/kernel-b930d107-f417-4580-9ca9-2dc63e5a26e4.json
As you can see, no Java heap parameters get passed to the process. According to the JVM logic the Java heap max size is set to 1/4 of the available RAM. In a containerized environment, the available RAM is the full RAM of the host/machine where the container is running, it is 16GB in my case. So the Scala kernel gets 4GB max heap size. Since I am running Jupyterhub in a container on Kubernetes, I have to set some reasonable memory limits for my pod. If I set it to anything lower than 4GB the kernel process will crash with OOM and get automatically restarted.
I’ve read this article about how I can pass JVM args to the Scala kernel. But in my case during kernel installation into my container image I don’t know the max heap size, that I will want to have at runtime. So I cannot really hardcode some fixed max heap size into my image.
It would be great to have a mechanism to be able to set Scala kernel max heap (and other JVM parameters) from environment variables. Something like JAVA_OPTS used in Apache Tomcat for example.
Issue Analytics
- State:
- Created 5 years ago
- Comments:7 (5 by maintainers)
@sbrunk I’m going to add support for reading
JAVA_OPTS
in bootstraps. (It should have been added long ago… Edit: done, https://github.com/coursier/coursier/pull/1118, should be included in the next coursier release)About launching
launcher.jar
orlauncher.bat
directly, this would require copying the launcher bat file along its jar on Windows (or generating our own bat file).Respecting container RAM limits has been backported to Java 8 as well. Since update 131 or so, it works if you add the the
-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap
JVM args. You should also add-XX:MaxRAMFraction=2
to use half of the available memory instead of 1/4. It’s still wasting memory though. Don’t be tempted to set-XX:MaxRAMFraction=1
as it will try to use all available container memory for the JVM which will get your pod killed.Since update 191, the experimental
-XX:+UseCGroupMemoryLimitForHeap
parameter has been replaced by-XX:+UseContainerSupport
which is enabled by default. Even better, it adds-XX:MaxRAMPercentage
as a replacement for-XX:MaxRAMFraction
which allows more fine control over how much memory the JVM gets.I.e. use
-XX:MaxRAMPercentage=75.0
depending on what else allocates memory in the container.The
openjdk:8-jre-alpine
is already at u191 whileopenjdk:8-jre-slim
seems to be still at u181 at the moment.See also the discussion in this SO thread.