一、JVM 架构基础

JVM 进程启动时,ClassLoader 会将需要的所有类加载到内存,主要分为以下三步:

  • Bootstrap Class: 核心类库,由 “Bootstrap Class Loader”负责加载, 例如基础的运行时类库 JRE\lib\rt.jar
  • Extension Classjava.ext.dirs 路径下的类,由 ExtClassLoader 负责加载。在实际开发中,如果需要添加额外的类库,通常放置于此位置。
  • Application Class: 实际应用包含的类,由 AppClassLoader 负责加载。

二、JVM 预热是指什么?

类加载过程完毕后,所有需要的类会进入 JVM cache (native code) ,这样就可以被快速的实时访问。当然,还有许多其它与JVM启动无关的类此时并未被加载。

当应用的第一个请求到来,会触发逻辑相关类的第一次加载,此过程会有一定的耗时,会影响第一次调用的实时响应。这主要是因为JVM的懒加载及JIT机制。因此对于低延迟应用,必须采用特定的策略来处理第一次的预加载逻辑,以保障第一次的请求的快速响应。此过程,我们称之为 JVM 的预热。

三、Tiered Compilation

JVM会将使用频率较高的方法放入本地缓存。以达到快速调用响应的目的。基于此,我们可以通过在应用启动之初,强制加载我们预先认知的高频方法。设置参数包括如下:

-XX:CompileThreshold -XX:TieredCompilation

通常虚拟机会通过解释器来收集反馈到编译器的方法调用信息。

四、自定义实现

基于上一小节所述,我们可以额外实现特定逻辑来进行特定方法的多次调用(-XX:CompileThreshold),以触发JVM的编译。如下示例:

首先,我们定义一个包含基础方法的类:

public class Dummy {

    public void m() {

    }
}

其次,我们创建一个加载类,在其内部添加静态方法,循环100000次重复生成Dummy对象,并调用其方法:

public class ManualClassLoader {

    protected static void load() {
for (int i = 0; i < 100000; i++) {
Dummy dummy = new Dummy();
dummy.m();
}
}
}

现在我们使用如下过程,测试性能:

public class MainApplication {

    static {
long start = System.nanoTime();
ManualClassLoader.load();
long end = System.nanoTime();
System.out.println("Warm Up time : " + (end - start));
} public static void main(String[] args) {
long start = System.nanoTime();
ManualClassLoader.load();
long end = System.nanoTime();
System.out.println("Total time taken : " + (end - start));
} }

如下为测试结果:

预热之后

未预热

差别(%)

1220056

8903640

730

1083797

13609530

1256

1026025

9283837

905

1024047

7234871

706

868782

9146180

1053

预热之后的性能明显好于未预热状态下的调用。

当然,这里只是一个简单的示例测试,具体到实际的应用中,还需要考虑特定的业务逻辑需求。

五、工具

通常用于基准测试,基本使用如下:

依赖 pom.xml:

<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>1.19</version>
</dependency> <dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>1.19</version>
</dependency>

maven库连接: Central Maven Repository

定义预热处理方法,并添加@Benchmark注解:

@Benchmark
public void init() { //code todo }

将需要预热的业务逻辑放置于预热处理方法内。

不可不知的 JVM 预热的更多相关文章

  1. 这些不可不知的JVM知识,我都用思维导图整理好了

    JVM是面试中必问的部分,本文通过思维导图以面向面试的角度整理JVM中不可不知的知识. 先上图: 1.JVM基本概念 1.1.JVM是什么 JVM 的全称是 「Java Virtual Machine ...

  2. 你可能不知道的jvm的类加载机制

    引言:在java代码中,类型的加载.连接与初始化过程都是在程序运行期间完成的. 加载:查找并加载类的二进制数据(class文件加载到内存中) 连接:a 验证:确保被加载类的正确性. b准备:为类的静态 ...

  3. 《The java.util.concurrent Synchronizer Framework》 JUC同步器框架(AQS框架)原文翻译

    一.论文简介 闲来无事,看看源码,发现了一篇JDK作者的论文<The java.util.concurrent Synchronizer Framework>主要描述了作者对Abstrac ...

  4. 重磅发布:阿里 OpenJDK终于开源啦! 将长期支持版本 Dragonwell

    前几天的北京阿里云峰会,阿里巴巴正式宣布对外开源 OpenJDK 长期支持版本 Alibaba Dragonwell.作为 Java 全球管理组织 Java Community Process (JC ...

  5. Dubbo 源码分析 - 集群容错之 LoadBalance

    1.简介 LoadBalance 中文意思为负载均衡,它的职责是将网络请求,或者其他形式的负载"均摊"到不同的机器上.避免集群中部分服务器压力过大,而另一些服务器比较空闲的情况.通 ...

  6. JUC同步器框架

    The java.util.concurrent Synchronizer Framework 前提 AQS(java.util.concurrent.locks.AbstractQueuedSync ...

  7. 微服务网关哪家强?一文看懂Zuul, Nginx, Spring Cloud, Linkerd性能差异

      导语:API Gateway是实现微服务重要的组件之一.面对诸多的开源API Gateway,如何进行选择也是架构师需要关注的焦点.本文作者对几个较大的开源API Gateway进行了压力测试,对 ...

  8. 一文讲透Dubbo负载均衡之最小活跃数算法

    本文是对于Dubbo负载均衡策略之一的最小活跃数算法的详细分析.文中所示源码,没有特别标注的地方均为2.6.0版本. 为什么没有用截止目前的最新的版本号2.7.4.1呢?因为2.6.0这个版本里面有两 ...

  9. 阿里开源 OpenJDK 发行版 Dragonwell

    日有消息显示,阿里将于 21 日重磅发布其 OpenJDK 发行版 Alibaba Dragonwell. 我们知道 OpenJDK 是基于 GPL v2/Classpath Exception 的 ...

随机推荐

  1. jRating五星评级

    <!DOCTYPE html> <html> <head> <title>jrating使用示例</title> <meta char ...

  2. Codeforces Global Round 8 A. C+=(贪心)

    题目链接:https://codeforces.com/contest/1368/problem/A 题意 给出 $a,b$,只可以使用 '+=' 运算符,问至少要使用多少次使得 $a$ 或 $b$ ...

  3. Codeforces Round #647 (Div. 2) - Thanks, Algo Muse! D. Johnny and Contribution (贪心,模拟)

    题意:有\(n\)个点,\(m\)条边,现在要给这些点赋值,,每次只能赋给某一点的四周(所连边)的最小没出现过的值.如果不能按照所给的数赋值,输出\(-1\),否则输出赋值顺序. 题解:我们用\(pa ...

  4. CF1462-E2. Close Tuples (hard version)

    本题为hard版,还有一个easy版,区别在于k和m的取值不同. 题意: 给出一个由n个数字组成的数组 \(a\).现在定义一种子集为\(\{A_1, A_2, A_3, ..., A_m\}\),使 ...

  5. 在kubernetes集群里集成Apollo配置中心(1)之交付Apollo-adminservice至Kubernetes集群

    1.部署apollo-adminservice软件包 apollo-adminservice软件包链接地址:https://github.com/ctripcorp/apollo/releases/d ...

  6. Nginx基础 - 常用模块配置

    1.Nginx状态监控http_stub_status_module记录Nginx客户端基本访问状态信息 location /mystatus { stub_status on; access_log ...

  7. ACM-ICPC 2018 徐州赛区网络预赛 B BE, GE or NE 【模拟+博弈】

    题目:戳这里 题意:A和B博弈,三种操作分别是x:加a,y:减b,z:取相反数.当x或y或z为0,说明该操作不可取,数据保证至少有一个操作可取,给定一个区间(l,k)和原始数字m,如果A和B在n次操作 ...

  8. 左神算法第五节课:认识哈希函数和哈希表,设计RandomPool结构,布隆过滤器,一致性哈希,岛问题,并查集结构

    认识哈希函数和哈希表 MD5Hash值的返回范围:0~9+a~f,是16位,故范围是0~16^16(2^64)-1, [Hash函数],又叫散列函数: Hash的性质: 1)  输入域无穷大: 2)  ...

  9. Mysql(三)------事务的特性、事务并发、事务读一致性问题

    1 什么是数据库的事务? 1.1 事务的典型场景 在项目里面,什么地方会开启事务,或者配置了事务?无论是在方法上加注解,还 是配置切面 <tx:advice id="txAdvice& ...

  10. 【rocketmq学习笔记】rocketmq入门学习

    基本介绍 rocketmq是阿里巴巴团队使用java语言开发的一款基于发布订阅模型的分布式消息队列中间件,是一款低延迟,高可用,拥有海量消息堆积能力和灵活拓展性的消息队列. 特点 可以实现集群无单点故 ...