Java 实战虚拟机 进阶 (一 万字)

实战 Java 虚拟机-高级篇

什么是 GraalVM

GraalVM 是 Oracle 官方推出的一款 **高性能JDK,**使用它享受比 OpenJDK 或者 OracleJDK 更好的性能。

  • GraalVM 的官方网址:https://www.graalvm.org/
  • 官方标语:Build faster, smaller, leaner applications.
  • 更低的 CPU、内存使用率

image-20241012154553514

  • 官方标语:Build faster, smaller, leaner applications.
  • 更低的CPU、内存使用率
  • 更快的启动速度,无需预热即可获得最好的性能
  • 更好的安全性、更小的可执行文件
  • 支持多种框架Spring Boot、Micronaut、Helidon 和 Quarkus。多家云平台支持。
  • 通过 Truffle框架运行 JS、Python、Ruby等其他语言。

image-20241012154725737

GraalVM 的版本

GraalVM 分为社区版(Community Edition)和企业版(Enterprise Edition)。企业版相比较社区版,在性能上有更多的优化。

image-20241012154932073

GraalVM 社区版环境搭建

image-20241012155004888

GraalVM 的两种运行模式

JIT (Just-In-Time) 模式,即时编译模式

JIT 模式的处理方式与 Oracle JDK类似,满足两个特点:

  • Write Once,Run Anywhere ->一次编写,到处运行。
  • 预热之后,通过 内置的Graal即时编译器 优化热点代码,生成比 Hotspot JIT 更高性能的机器码。

image-20241012155747330

image-20241012155938711

AOT (Ahead-Of-Time)模式,提前编译模式

AOT 编译器通过源代码,为特定平台创建可执行文件。比如,在Windows下编译完成之后,会生成 exe文件。通过这种方式,达到启动之后获得最高性能的目的。但是不具备跨平台特性,不同平台使用需要单独编译。这种模式生成的文件称之为Native Image本地镜像。

image-20241012160426792

image-20241012160506620

官网:https://www.graalvm.org/latest/reference-manual/native-image/#prerequisites

GraalVM 模式和版本的性能对比

社区版的GraalVM 使用本地镜像模式性能不如 HotspotJVM 的 JIT 模式,但是企业版的性能相对会高很多

image-20241012162306816

GraalVM 存在的问题

GraaIVM 的 AOT模式虽 然在启动速度、内存和CPU开销上非常有优势,但是使用这种技术会带来几个问题:

1、跨平台问题,在不同平台下运行需要编译多次。编译平台的依赖库等环境要与运行平台保持一致。
2、使用框架之后,编译本地镜像的时间比较长,同时也需要消耗 大量的CPU 和 内存。
3、AOT编译器 在编译时,需要知道运行时所有可访问的所有类。但是 Java 中有一些技术可以在运行时创建类,例如反射、动态代理等。这些技术在很多框架比如Spring中大量使用,所以框架需要 对AOT编译器进行适配解决类似的问题。

image-20241012162500806

实战案例1:使用 SpringBoot3 搭建 GraalVM 环境

image-20241012162707457

应用场景

image-20241012163559016

GraalVM 企业级应用 - Serverless 架构

传统的系统架构中,服务器等基础设施的运维、安全、高可用等工作都需要企业自行完成,存在两个主要问题:

1、开销大,包括了人力的开销、机房建设的开销。
2、**资源浪费,面对一些突发的流量冲击,比如秒杀等活动,必须提前规划好容量准备好大量的服务器,**这些服务器在其他时候会处于闲置的状态,造成大量的浪费。

image-20241012163832045

随着虚拟化技术、云原生技术的愈发成熟,云服务商提供了一套称为 Serverless无服务器化的 架构。企业无需进行服务器的任何配置和部署,完全由云服务商提供。比较 典型的有亚马逊 AWS、阿里云等 。

image-20241012163946250

Serverless架构 - 函数计算

Serverless架构 中第一种常见的服务是函数计算(Function as a Service),将一个应用拆分成多个函数,每个函数会以事件驱动的方式触发。典型代表有 AWS 的 Lambda、阿里云的 FC。

image-20241012164209647

函数计算主要应用场景有如下几种:

① 小程序、API服务 中的接口,此类接口的调用频率不高,使用常规的服务器架构容易产生资源浪费,使用 Serverless 就可以实现按需付费降低成本,同时支持自动伸缩能应对流量的突发情况。
② 大规模任务的处理,比如 音视频文件转码、审核等,可以利用事件机制当文件上传之后,自动触发对应的任务。
函数计算的计费标准中 包含CPU和内存使用量,所以使用 GraaIVM AOT模式 编译出来的本地镜像可以节省更多的成本。

函数计算的计费标准中 包含CPU和内存使用量,所以使用 GraaIVM AOT模式编译 出来的本地镜像可以节省更多的成本。

image-20241012164714003

实战案例 2:将程序部署到阿里云函数计算

image-20241012164827347

Serverlesss 架构 -Serverless 应用

函数计算的服务资源比较受限,比如 AWS 的Lambda 服务一般 无法支持超过15分钟的函数执行,所以云服务商提供了另外一套方案:基于容器的Serverless 应用,无需手动配置 K8s中 的 Pod、Service 等内容,只需选择镜像就可自动生成应用服务。

同样,Serverless应用 的计费标准中 包含CPU和内存使用量,所以 使用GraaIVM AOT模式 编译出来的本地镜像 可以节省更多的成本。

image-20241012165900643

将程序部署到 阿里云 Serverless 应用

步骤:

1、在项目中编写 Dockerfile 文件。
2、使用服务器制作镜像,这一步会消耗大量的CPU和内存资源,同时 GraaIVM相关 的镜像服务器在国外,**建议使用阿里云的镜像服务器制作Docker镜像。**前两步同实战案例2
3、配置Serverless应用,选择容器镜像、CPU和内存。
4、绑定外网负载均衡并使用 Postman 进行测试。

参数优化和故障诊断

GraalVM 的内存参数

由于 GraalVM 是一款独立的 JDK,所以大部分 HotSpot 中的虚拟机参数都不适用。常用的参数参考:官方手册

  • 社区版只能使用串行 垃圾回收器(Serial GC),使用串行垃圾回收器的默认 最大Java 堆大小 会设置为物理内存大小的 80%,调整方式为使用 -Xmx最大堆大小。如果希望在编译期就指定该大小,可以在编译时添加参数 -R:MaxHeapSize=最大堆大小。
  • G1垃圾回收器只能在企业版中使用,开启方式为添加 --gC=G1参数,有效降低垃圾回收的延迟。
  • 另外提供一个Epsilon GC,开启方式:–gc=epsilon,它不会产生任何的垃圾回收行为所以没有额外的内存、CPU开销。如果在公有云上运行的程序生命周期短暂不产生大量的对象,可以使用该垃圾回收器,以节省最大的资源。
  • -XX:+PrintGC -XX:+VerboseGC 参数打印垃圾回收详细信息。
实战案例4:内存快照文件的获取

image-20241012171142190

实战案例5:运行时数据的获取

image-20241012172132450

总结

image-20241012172507863

新一代的GC

垃圾回收器的技术演进

image-20241012173037234

不同的垃圾回收器设计的目标是不同的,如下图所示:

image-20241012173146626

Shenandoah GC

Shenandoah 是由 Red Hat 开发的一款低延迟的垃圾收集器,Shenandoah 并发执行大部分 GC 工作,包括并发的整理,堆大小对 STW的时间 基本没有影响。

image-20241012173527082

Shenandoah 的使用方法

1、下载。Shenandoah 只包含在 Open JDK中,默认不包含在内需要单独构建,可以直接下载构建好的。

下载地址: https://builds.shipilev.net/openjdk-jdk-shenandoah/

选择方式如下:

image-20241012173735360

image-20241012173902676

ZGC

ZGC 是一种可扩展的低延迟垃圾回收器。ZGC 在垃圾回收过程中,STW 的时间不会超过一毫秒,适合需要低延迟的应用。支持 几百兆 到 16TB 的堆大小,堆大小对 STW 的时间基本没有影响。ZGC 降低了停顿时间,能降低接口的最大耗时,提升用户体验。但是吞吐量不佳,所以 如果Java服务 比较关注 QPS(每秒的查询次数)那么 G1是 比较不错的选择。

image-20241012174934173

ZGC 的版本更选

image-20241012175136688

OracleJDK 和 OpenJDK 中都支持 ZGC,阿里的 DragonWell 龙井JDK 也支持 ZGC 但属于其自行对 Open JDK 11 的 ZGC 进行优化的版本。
建议使用 JDK17 之后的版本,延迟较低同时无需手动配置并行线程数。

image-20241012175243422

ZGC 在设计上做到了自适应,根据运行情况自动调整参数,让用户手动配置的参数最少化。

  • 自动设置年轻代大小,无需设置 -Xmn参数。
  • 自动晋升阈值(复制中存活多少次才搬运到老年代),无需设置 -XX:TenuringThreshold。
  • JDK17 之后支持自动的并行线程数,无需设置 -XX:ConcGCThreads。
ZGC 的参数设置

image-20241012175603648

ZGC 的调优

ZGC 中可以使用 Linux 的 Huge Page 大页技术优化性能,提升吞吐量、降低延迟。
注意:安装过程需要 root 权限,所以 ZGC 默认没有开启此功能。

操作步骤:

1、计算所需页数,Linuxx86 架构中大页大小为 2MB,根据所需堆内存的大小估算大页数量。比如堆空间需要 16G,预留 2G( JVM 需要额外的一些非堆空间),那么页数就是 18G / 2MB = 9216。
2、配置系统的大页池以具有所需的页数(需要root权限):
$ echo 9216 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
3、添加参数 -XX:+UseLargePages 启动程序进行测试

实战案例

内存不足时的垃圾回收测试

image-20241012193452255

总结

image-20241012194656868

揭秘 Java 工具

在 Java 的世界中,除了 Java 编写的业务系统之外,还有一类程序也需要 Java程序员 参与编写,这类程序就是 Java工具。
常见的 Java工具 有以下几类:
1、诊断类工具,如 Arthas、VisualVM 等。
2、开发类工具,如 ldea、Eclipse。
3、APM 应用性能监测工具,如 Skywalking、Zipkin 等。
4、热部署工具,如 Jrebel 等。

image-20241012194931547

学习 Java 工具常用技术 Java Agent

Java Agent技术是 JDk 提供的用来编写 Java工具 的技术,使用这种技术生成一种特殊的 jar包,这种 jar包 可以让 Java程序 运行其中的代码。

image-20241012195349431

Java Agent 技术的两种模式-静态加载模式

静态加载模式可以在程序启动的一开始就执行我们需要执行的代码,适合用 APM等性能监测系统 从一开始就监控程序的执行性能。静态加载模式需要在Java Agent的项目中编写一个 premain 的方法,并打包成jar包。

image-20241012195559233

搭建 java agent静态加载模式的环境

111

maven 环境配置Maven重点学习笔记(包入门 2万字)

image-20241012200142572

Java代码
import java.lang.instrument.Instrumentation;

public class AgentMain {
   
   
    // premain 方法
    public static void premain(String agentArgs, Instrumentation inst) {
   
   
        System.out.println("premain执行了");
        
    }
}
Java Agent技术的两种模式-动态加载模式

动态加载模式可以随时让 java agent代码执行,适用于 Arthas等诊断系统。动态加载模式需要在 Java Agent的项目中编写一个 agentmain 的方法,并打包成 jar包。

image-20241012195756051

搭建 java agent 动态加载模式的环境

image-20241012201851700

Java 代码
import com.sun.tools.attach.AttachNotSupportedException;
import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.AttachNotSupportedException;
import com.sun.tools.attach.VirtualMachine;

import java.io.IOException;

public class AttachMain {
   
   
    public static void main(String[] args) throws IOException, AttachNotSupportedException {
   
   
        // 获取进程虚拟对象
        VirtualMachine vm = VirtualMachine.attach("37632");
        // 执行Java agent里面的 agentmain 方法
        vm.loadAgent("D:/jvm/javaagent/itheima-agent/target/itheima-agent-1.0-SNAPSHOT-jar-with-dependencide");
        
        
    }
}

实战案例

实战案例1:简化版的 Arthas
需求:

编写一个简化版的 Arthas程序,具备以下几个功能:
1、查看内存使用情况
2、生成堆内存快照
3、打印栈信息
4、打印类加载器
5、打印类的源码
6、打印方法执行的参数和耗时

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值