New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

jlink runtime image size (specifically libjvm.so) created from openjdk is huge. Expected it to be much smaller. #217

Open
testphreak opened this Issue Jul 23, 2018 · 13 comments

Comments

Projects
None yet
10 participants
@testphreak

testphreak commented Jul 23, 2018

Description

When building a Docker image for a service based on OpenJDK base image, I noticed that the runtime image created is 346Mb (and specifically the file libjvm.so under /lib/security) in size as compared to OracleLinux base image which creates a runtime image of 49Mb. What is the reason for this huge disparity in size?

I have tried building from different variants of 10 and 11 base images, but I still see the large runtime size.

Configuration

Docker -

Client:
 Version:      18.03.1-ce
 API version:  1.37
 Go version:   go1.9.5
 Git commit:   9ee9f40
 Built:        Thu Apr 26 07:13:02 2018
 OS/Arch:      darwin/amd64
 Experimental: false
 Orchestrator: swarm

Server:
 Engine:
  Version:      18.03.1-ce
  API version:  1.37 (minimum version 1.12)
  Go version:   go1.9.5
  Git commit:   9ee9f40
  Built:        Thu Apr 26 07:22:38 2018
  OS/Arch:      linux/amd64
  Experimental: true

macOS - Sierra (10.12.6)

Dockerfile -

FROM openjdk:10.0.2-slim

RUN jlink \
    --add-modules java.xml.bind,java.sql,java.naming,java.management,java.instrument,java.security.jgss \
    --verbose \
    --strip-debug \
    --compress 2 \
    --no-header-files \
    --no-man-pages \
    --output /opt/jre-minimal

CMD du -sh /opt/jre-minimal

Actual Results

docker run --name ojdk -it openjdk_test
346M	/opt/jre-minimal

Digging a little deeper, it appears the primary reason for this bloat is libjvm.so.

docker run --rm --name openjdk_image_size -it openjdk_test ls -la /opt/jre-minimal/lib/server
total 308028
drwxr-xr-x 2 root root      4096 Jul 23 17:58 .
drwxr-xr-x 5 root root      4096 Jul 23 17:58 ..
-rw-r--r-- 1 root root      1322 Jul 23 17:58 Xusage.txt
-rw-r--r-- 1 root root     24992 Jul 23 17:58 libjsig.so
-rw-r--r-- 1 root root 315379056 Jul 23 17:58 libjvm.so

Expected Results
Expect a much smaller runtime image. For example if I use Oracle Linux as base image,

Dockerfile -

FROM oraclelinux:7-slim

RUN yum -y install wget tar gzip && yum clean all \
    && wget -q https://download.java.net/java/GA/jdk10/10.0.2/19aef61b38124481863b1413dce1855f/13/openjdk-10.0.2_linux-x64_bin.tar.gz \
        -P /opt/jdk \
    && tar -xzf /opt/jdk/openjdk-10.0.2_linux-x64_bin.tar.gz -C /opt/jdk \
    && rm /opt/jdk/openjdk-10.0.2_linux-x64_bin.tar.gz

ENV PATH=${PATH}:/opt/jdk/jdk-10.0.2/bin

RUN jlink \
    --add-modules java.xml.bind,java.sql,java.naming,java.management,java.instrument,java.security.jgss \
    --verbose \
    --strip-debug \
    --compress 2 \
    --no-header-files \
    --no-man-pages \
    --output /opt/jre-minimal

CMD du -sh /opt/jre-minimal

I get a 49Mb image size, which is expected.

docker run --name oracle_linux_jdk -it oraclelinux_jdk_test
49M	/opt/jre-minimal

@wglambert wglambert added the question label Jul 23, 2018

@tianon

This comment has been minimized.

Member

tianon commented Jul 23, 2018

For the slim images, we consume Debian's OpenJDK packages directly, so unfortunately there's not much we can do here besides recommending taking this up with the Debian package maintainer to try to determine why libjvm.so is so large.

@testphreak

This comment has been minimized.

testphreak commented Jul 24, 2018

@tianon it is not just for the slim image. Even the regular images have the problem. Could you build an image from the Dockerfile I provided above to confirm the issue? Just want to make sure it's not machine or Docker specific.

@feskehau

This comment has been minimized.

feskehau commented Jul 24, 2018

I have the exact same issue, runing the same jlink command on my local machine creates runtime of about 40 mb, the same command in a container creates a runtime image of 350 mb. Have been debuging all that i can, must be something with the image.

@feskehau

This comment has been minimized.

feskehau commented Jul 24, 2018

Tried with slim and reguler, same issue

@panga

This comment has been minimized.

panga commented Jul 24, 2018

I've verified and the problem started in OpenJDK 10.0.2 (10.0.1 works as expected, small size).
OpenJDK 11 (ea) is also affected.

Note: I couldn't reproduce this downloading the OpenJDK builds from http://jdk.java.net, the issue appears to be something with the OpenJDK builds used by the images on this repo.

@panga

This comment has been minimized.

panga commented Jul 24, 2018

For comparison:

OpenJDK 11+23

dockerhub image:
404.5M ./lib/server/libjvm.so

downloaded from jdk.java.net:
22M ./lib/server/libjvm.so

@tianon

This comment has been minimized.

Member

tianon commented Jul 24, 2018

panga added a commit to panga/hammock-jpms that referenced this issue Jul 24, 2018

panga added a commit to panga/spring-petclinic that referenced this issue Jul 24, 2018

panga added a commit to panga/spring-petclinic that referenced this issue Jul 24, 2018

@anthraxx

This comment has been minimized.

anthraxx commented Aug 6, 2018

Back reference to the debian ticket: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=905575

@robilad

This comment has been minimized.

robilad commented Sep 26, 2018

Yeah, in their 10.0.2 build, doko added * Configure with --with-native-debug-symbols=internal.
according to https://tracker.debian.org/news/974018/accepted-openjdk-10-100213-1-source-into-unstable/

See http://hg.openjdk.java.net/jdk/jdk11/raw-file/tip/doc/building.html#native-debug-symbols for details of the option.

@ddriddle

This comment has been minimized.

ddriddle commented Oct 16, 2018

As a workaround if you run strip on libjvm.so it cuts the file size from 421M down to only 18M!

$ strip -p --strip-unneeded lib/server/libjvm.so
@barchetta

This comment has been minimized.

barchetta commented Nov 5, 2018

I've run into this problem as well, but am somewhat confused by the root cause. The libjvm.so contained in the base image is stripped, but after I run jlink the libjvm.so in the generated JRE is not stripped! Where did the not-stripped libjvm.so come from?

$ docker run -it --rm openjdk:11-slim  bash

root@82053b2068e1:/# apt update
root@82053b2068e1:/# apt install file

root@82053b2068e1:/# file /usr/lib/jvm/java-11-openjdk-amd64/lib/server/libjvm.so
/usr/lib/jvm/java-11-openjdk-amd64/lib/server/libjvm.so: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=d0ad517c66e394d71daa113ecaccbc398ac6d862, stripped

root@82053b2068e1:/# ls -sh /usr/lib/jvm/java-11-openjdk-amd64/lib/server/libjvm.so
18M /usr/lib/jvm/java-11-openjdk-amd64/lib/server/libjvm.so

root@82053b2068e1:/# /usr/lib/jvm/java-11-openjdk-amd64/bin/jlink --add-modules java.base --output /var/tmp/myjre

root@82053b2068e1:/# file /var/tmp/myjre/lib/server/libjvm.so
/var/tmp/myjre/lib/server/libjvm.so: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=d0ad517c66e394d71daa113ecaccbc398ac6d862, with debug_info, not stripped

root@82053b2068e1:/# ls -sh /var/tmp/myjre/lib/server/libjvm.so
421M /var/tmp/myjre/lib/server/libjvm.so

I also tried passing --strip-debug to jlink and that did not help.

@yosifkit

This comment has been minimized.

Member

yosifkit commented Nov 6, 2018

As noted in the linked Debian bug, the problem is not the size of the system libjvm.so, but the one contained in the zip /usr/lib/jvm/java-10-openjdk-amd64/jmods/java.base.jmod (and 11):

$ docker run -it --rm -w /tmp openjdk:11-slim bash
root@2b88d78d9a67:/tmp# ls -lh /usr/lib/jvm/java-11-openjdk-amd64/lib/server/libjvm.so
-rw-r--r-- 8 root root 18M Oct 17 07:31 /usr/lib/jvm/java-11-openjdk-amd64/lib/server/libjvm.so
root@2b88d78d9a67:/tmp# ls -lh /usr/lib/jvm/java-11-openjdk-amd64/jmods/java.base.jmod
-rw-r--r-- 8 root root 154M Oct 17 07:31 /usr/lib/jvm/java-11-openjdk-amd64/jmods/java.base.jmod
root@2b88d78d9a67:/tmp# unzip /usr/lib/jvm/java-11-openjdk-amd64/jmods/java.base.jmod
....
root@2b88d78d9a67:/tmp# ls -lh lib/server/
total 421M
-rw-r--r-- 1 root root 1.3K Oct 17 16:52 Xusage.txt
-rw-r--r-- 1 root root  25K Oct 17 16:51 libjsig.so
-rw-r--r-- 1 root root 421M Oct 17 16:51 libjvm.so
@ddriddle

This comment has been minimized.

ddriddle commented Nov 6, 2018

@barchetta as I noted above if you run the command strip directly on libjvm.so after you build the JRE it will cut the size of the file from 421 M to 18 M. I have no idea why the jlink strip does not work. Based on the example you gave:

$ docker run -it --rm openjdk:11-slim  bash

root@3c96831af8eb:/# apt update
root@3c96831af8eb:/# apt install -y file

root@3c96831af8eb:/# /usr/lib/jvm/java-11-openjdk-amd64/bin/jlink -G --add-modules java.base --output /var/tmp/myjre

root@3c96831af8eb:/# file /var/tmp/myjre/lib/server/libjvm.so
/var/tmp/myjre/lib/server/libjvm.so: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=d0ad517c66e394d71daa113ecaccbc398ac6d862, with debug_info, not stripped

root@3c96831af8eb:/# ls -sh /var/tmp/myjre/lib/server/libjvm.so
421M /var/tmp/myjre/lib/server/libjvm.so

######## WORKAROUND STARTS HERE #################

root@3c96831af8eb:/# apt-get install -y binutils
root@3c96831af8eb:/# strip -p --strip-unneeded /var/tmp/myjre/lib/server/libjvm.so

root@3c96831af8eb:/# file /var/tmp/myjre/lib/server/libjvm.so
/var/tmp/myjre/lib/server/libjvm.so: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=d0ad517c66e394d71daa113ecaccbc398ac6d862, stripped

root@3c96831af8eb:/# ls -sh /var/tmp/myjre/lib/server/libjvm.so
18M /var/tmp/myjre/lib/server/libjvm.so
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment