Skip to content
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

Closed
testphreak opened this issue Jul 23, 2018 · 15 comments · Fixed by #322
Labels
question Usability question, not directly related to an error with the image

Comments

@testphreak
Copy link

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 Usability question, not directly related to an error with the image label Jul 23, 2018
@tianon
Copy link
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
Copy link
Author

@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
Copy link

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
Copy link

Tried with slim and reguler, same issue

@panga
Copy link

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
Copy link

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
Copy link
Member

tianon commented Jul 24, 2018 via email

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
Copy link

anthraxx commented Aug 6, 2018

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

@robilad
Copy link

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
Copy link

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
Copy link

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
Copy link
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
Copy link

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

@zhedan

This comment has been minimized.

@TreeFrogApps

This comment has been minimized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Usability question, not directly related to an error with the image
Projects
None yet
Development

Successfully merging a pull request may close this issue.