V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
louislivi
V2EX  ›  Java

利用 OpenJ9 大幅度降低 Java 内存占用

  •  4
     
  •   louislivi · Jul 1, 2020 · 9083 views
    This topic created in 2132 days ago, the information mentioned may be changed or developed.

    OpenJ9

    OpenJ9

    介绍

    • OpenJ9 是一种高性能,可扩展的 Java™虚拟机( VM )实现,完全符合 Java 虚拟机规范。

    • 在运行时,VM 解释由 Java 编译器编译的 Java 字节码。VM 充当语言与底层操作系统和硬件之间的翻译器。Java 程序需要特定的 VM 才能在特定的平台(例如 Linux®,z /OS®或 Windows™)上运行。

    • OpenJ9 VM 会自动检测它何时在 docker 容器中运行,并使用一种机制来检测 VM 何时处于空闲状态。当检测到空闲状态时,OpenJ9 会运行垃圾回收周期,并将可用内存页释放回操作系统。还压缩对象堆,以充分利用可用内存来进行进一步的应用程序处理。对于基于内存使用量收费的云服务,保持较小的占用空间可以节省成本。

    好处

    • 内存占用少
    • 启动时间短
    • 吞吐量高
    • 更加适合微服务以及容器

    性能

    • 启动后占比减少 66 % 启动后占比减少 66 % OpenJ9 针对云工作负载进行了高度优化,在这些工作中,内存占用小非常重要。即使启用了其他优化,占用空间仍保持不变。

    • 高负载期间的占比减少了 63 % 高负载期间的占比减少了 63 % 当施加负载时,内存占用量迅速增加,但是在稳定状态下,带有 OpenJ9 的 OpenJDK 8 使用的物理内存比带有 HotSpot 的 OpenJDK 8 少大约 63 %。

    • 启动时间加快 42 % 启动时间加快 42 % 共享类和预编译( AOT )技术通常会减少启动时间。通过同时使用-Xquickstart 模式,可以将启动时间最多减少 42 %。

    • 达到同样的吞吐量 达到同样的吞吐量 尽管带有 OpenJ9 的 OpenJDK 8 和带有 Hotspot 的 OpenJDK 8 都达到了相似的峰值吞吐量,但是带有 OpenJ9 的 OpenJDK 8 达到了约 1 分钟的峰值。

    • 在容器中的满载加速度 在容器中的满载加速度 OpenJ9 在 8.5 分钟内达到单个 CPU 内核的峰值吞吐量,而 Hotspot 则为 30 分钟。对于在资源受限的环境(例如容器​​)中运行的短期 VM 而言,更快地执行更多工作非常重要。

    这些结果表明,OpenJ9 在(通常是相互冲突的)性能指标之间达到了良好的平衡:借助 AOT 技术,它可以节省大量的空间并缩短启动时间,同时还提供与 Hotspot 竞争的吞吐量性能。 由于其内存占用量低,OpenJ9 特别适合于云计算环境,在这种环境中,节省内存可为云用户和提供商节省成本。

    实际使用

    目前我的项目是一个基于 Spring Boot 开发的,项目中加入了大量定时器以及多线程,网络 IO 请求,数据计算等。生产环境部署方式采用的Docker,之前是采用的官方的openjdk镜像,目前已经改为了openj9,至于为什么请看以下数据。

    我这里以比较突出的内存占用进行比较。

    服务器配置

    2 核 4G

    openjdk

    对应的Dockerfile

    FROM openjdk:8-jdk-alpine
    ADD target/app.jar app.jar
    ENTRYPOINT [ \
        "java", \
        "-XX:MetaspaceSize=256m", \
        "-XX:MaxMetaspaceSize=256m", \
        "-Xms2048m", \
        "-Xmx2048m", \
        "-Xmn256m", \
        "-Xss256k", \
        "-XX:SurvivorRatio=8", \
        "-XX:+UseConcMarkSweepGC", \
        "-Duser.timezone=GMT+08", \
        "-Djava.security.egd=file:/dev/./urandom", \
        "-jar", \
        "/app.jar", \
        "--spring.profiles.active=prod" \
    ]
    

    运行 2 小时后内存占用情况: openjdk 运行 2 小时后内存占用情况 后续运行更久时甚至达到了90%以上。 90%以上

    openj9

    对应的Dockerfile

    FROM adoptopenjdk:8-jdk-openj9
    ADD target/app.jar app.jar
    ENTRYPOINT [ \
        "java", \
        "-XX:MetaspaceSize=256m", \
        "-XX:MaxMetaspaceSize=256m", \
        "-Xms2048m", \
        "-Xmx2048m", \
        "-Xmn256m", \
        "-Xss256k", \
        "-XX:SurvivorRatio=8", \
        "-XX:+UseConcMarkSweepGC", \
        "-Duser.timezone=GMT+08", \
        "-Djava.security.egd=file:/dev/./urandom", \
        "-Xshareclasses", \
        "-Xquickstart", \
        "-jar", \
        "/app.jar", \
        "--spring.profiles.active=prod" \
    ]
    

    运行 2 小时后内存占用情况: openj9 运行 2 小时后内存占用 后续运行更久也没有明显变化。 后续运行更久也没有明显变化

    最后从数据看来结果,内存占用真的低,非常节省服务器资源,相同负载下至少节省一半的服务器资源。 值得推荐大家去尝试。

    Supplement 1  ·  Jul 2, 2020
    官方文档地址: https://www.eclipse.org/openj9/
    25 replies    2020-07-02 18:20:39 +08:00
    gz911122
        1
    gz911122  
       Jul 1, 2020
    挺有意思的.. 收藏了. 下次试试.
    tt0411
        2
    tt0411  
       Jul 1, 2020
    OpenJ9 对于 sun.* 包支持如何?
    whileFalse
        3
    whileFalse  
       Jul 1, 2020
    好奇它是怎么做到的
    GM
        4
    GM  
       Jul 1, 2020
    已经在我公司生产环境用了半年多了,具体性能多好、多省内存目前没感觉 ,因为业务量还没触及服务器极限。

    但是说没稳定性是没问题的。
    cubecube
        5
    cubecube  
       Jul 1, 2020 via Android
    我记得看过很多分析测评,速度不如官方。
    nutting
        6
    nutting  
       Jul 1, 2020
    个人开发呢,也想省点内存
    wysnylc
        7
    wysnylc  
       Jul 1, 2020
    对个人开发者持保守态度
    GM
        8
    GM  
       Jul 1, 2020
    @wysnylc OpenJ8 是 IBM 出品的,并不是个人开发者。
    donnior
        9
    donnior  
       Jul 1, 2020
    wysnylc
        10
    wysnylc  
       Jul 1, 2020
    @GM #8 还以为是个人的呢,孤陋寡闻了
    cheng6563
        11
    cheng6563  
       Jul 1, 2020 via Android
    加密库貌似有点差别
    liamyoung
        12
    liamyoung  
       Jul 1, 2020
    看一遍官方文档,还不错
    raphael008
        13
    raphael008  
       Jul 1, 2020
    openj9 挺好的一直在用没啥 performance issue,因为公司只让用自家的😂(
    Anarchy
        14
    Anarchy  
       Jul 1, 2020
    我用 AndroidStudio 内存总是紧张,个人电脑装个看看有效果没
    keshawnvan
        15
    keshawnvan  
       Jul 1, 2020
    之前试过,内存确实降了不少
    40EaE5uJO3Xt1VVa
        16
    40EaE5uJO3Xt1VVa  
       Jul 1, 2020
    yuekcc
        17
    yuekcc  
       Jul 1, 2020
    在生产环境也用过一段时间。稳定性没有问题,内存占用的确更少,适合在单机上部署多个服务。性能估计会比 hotspot 弱一些,没有仔细压测,有得有失吧。就是感觉开发有点慢。

    @yanzhiling2001 手动点赞
    salmon5
        18
    salmon5  
       Jul 1, 2020
    建议 hotspot 用 adoptopenjdk:8-jdk-hotspot
    openbsd
        19
    openbsd  
       Jul 2, 2020
    IBM 优化版 ?
    hantsy
        20
    hantsy  
       Jul 2, 2020
    运行时内存占用,和 Java 应用的实际性能不完全是一回事。从我以前看到的一些文章来看,OpenJ9 在 X86 架构上,整体性能并没什么优势,很多方面甚至落后 Hotspot 很远。以前在 X86 上性能最出色的 BEA 的 JRocket 。BEA 被 Oracle 收购,现在 JRocket 优秀的部分不知道有没有进入 OpenJDK 。

    @tt0411 你这个是 Java 语言 API 层面的,和底层 JVM 实现没关系。AdoptOpenJDK 有针对不同的 JVM 打包的版本。com.sun 在实际项目中要避免使用,IBM 的 JDK 就可能就不包含这些 API 了。
    hantsy
        21
    hantsy  
       Jul 2, 2020
    这个比较对 Hotspot 很不公平,把 CDS 和 AOT 加上 OpenJ9 后与裸的 Hotspot 有什么意义。

    CDS,AOT 和 GraalVM 一些成果都是在慢慢回到 OpenJDK,将来 AOT 会标准化。
    hantsy
        22
    hantsy  
       Jul 2, 2020
    目前还是 Hotspot 比较大众化。对于写应用程序层面来讲关系不大,部署上可以考虑不同 JVM 。
    hantsy
        23
    hantsy  
       Jul 2, 2020
    salmon5
        24
    salmon5  
       Jul 2, 2020
    内存是省了,稳定性和性能给牺牲了
    gz911122
        25
    gz911122  
       Jul 2, 2020
    @hantsy
    运行时内存占用,和 Java 应用的实际性能不完全是一回事

    > 那 openj9 的内存占用是真的小吗? 因为对于个人开发者来说, 性能是个比较次要的问题. 反而节约资源比较重要.
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   901 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 73ms · UTC 23:05 · PVG 07:05 · LAX 16:05 · JFK 19:05
    ♥ Do have faith in what you're doing.