JIT编程与方法内联

JIT的比较冷门,首先你要读一下这两篇 帖子:

《面向JIT编程-方法内联》 https://blog.csdn.net/u012834750/article/details/79488572

《浅谈对JIT编译器的理解》 https://www.cnblogs.com/insistence/p/5901457.html

后面就是实战的内容了:

一、我们先看方法内联:

根据帖子里面说的,方法内联只会发生在private方法中,那我们来看一下是不是这样。

1 public static void main(String[] args) throws ClassNotFoundException { 2 for (int i = 0; i < 1000000; i++) { 3 name(i); 4 } 5 } 6 7 public static void name(int k) { 8 for (int i = 0; i < k; i++) { 9 name1(i); 10 } 11 } 12 13 private static void name1(int i) { 14 i = i * 100; 15 } 16}

用javac命令编译后,用javap命令查看汇编情况,发现私有函数name1()被内联,我们知道内联最大的好处就是去掉了压栈 弹栈,提升性能。

1D:\software\eclipse\eclipse-workspace_solo\TESTTT\src>javap -c Main2 2Compiled from "Main2.java" 3public class Main2 { 4 public Main2(); 5 Code: 6 0: aload_0 7 1: invokespecial #1 // Method java/lang/Object."<init>":()V 8 4: return 9 10 public static void main(java.lang.String[]) throws java.lang.ClassNotFoundException; 11 Code: 12 0: iconst_0 13 1: istore_1 14 2: iload_1 15 3: ldc #2 // int 1000000 16 5: if_icmpge 18 17 8: iload_1 18 9: invokestatic #3 // Method name:(I)V 19 12: iinc 1, 1 20 15: goto 2 21 18: return 22 23 public static void name(int); 24 Code: 25 0: iconst_0 26 1: istore_1 27 2: iload_1 28 3: iload_0 29 4: if_icmpge 17 30 7: iload_1 31 8: invokestatic #4 // Method name1:(I)V 32 11: iinc 1, 1 33 14: goto 2 34 17: return 35}

二、下面我们来看一下JIT编译:

先看下面代码:

1public class Main2 { 2 public static void main(String[] args) throws ClassNotFoundException { 3 for (int i = 0; i < 1000000; i++) { 4 name(i); 5 } 6 } 7 8 public static void name(int k) { 9 for (int i = 0; i < k; i++) { 10 name1(i); 11 } 12 } 13 14 private static void name1(int i) { 15 i = i * 100; 16 } 17}

编译后,我们进行运行,但在运行的时候,加上:-XX:+PrintCompilation 参数,这样会把JIT编译的参数打印出来。

1D:\software\eclipse\eclipse-workspace_solo\TESTTT\src>java -XX:+PrintCompilation Main2 2 71 1 3 java.lang.String::hashCode (55 bytes) 3 72 2 3 java.lang.String::equals (81 bytes) 4 73 3 4 java.lang.String::charAt (29 bytes) 5 73 4 3 java.lang.String::<init> (82 bytes) 6 74 10 4 java.lang.String::length (6 bytes) 7 74 6 3 java.lang.Character::toLowerCase (9 bytes) 8 74 11 n 0 java.lang.System::arraycopy (native) (static) 9 75 7 3 java.lang.CharacterData::of (120 bytes) 10 75 8 3 java.lang.CharacterDataLatin1::toLowerCase (39 bytes) 11 76 9 3 java.lang.CharacterDataLatin1::getProperties (11 bytes) 12 76 5 3 java.util.Arrays::copyOfRange (63 bytes) 13 80 12 3 java.lang.Object::<init> (1 bytes) 14 81 13 3 java.lang.AbstractStringBuilder::ensureCapacityInternal (27 bytes) 15 82 15 3 java.lang.String::indexOf (70 bytes) 16 82 17 1 java.lang.Object::<init> (1 bytes) 17 82 12 3 java.lang.Object::<init> (1 bytes) made not entrant 18 83 14 3 java.lang.AbstractStringBuilder::append (29 bytes) 19 84 18 3 java.io.WinNTFileSystem::isSlash (18 bytes) 20 84 19 s 3 java.lang.StringBuffer::append (13 bytes) 21 85 16 3 java.lang.StringBuilder::append (8 bytes) 22 85 20 3 java.lang.AbstractStringBuilder::append (50 bytes) 23 88 21 3 Main2::name1 (6 bytes) 24 88 22 3 Main2::name (18 bytes) 25 88 23 1 Main2::name1 (6 bytes) 26 89 24 % 4 Main2::name @ 2 (18 bytes) 27 90 21 3 Main2::name1 (6 bytes) made not entrant 28 91 25 4 Main2::name (18 bytes) 29 91 22 3 Main2::name (18 bytes) made not entrant 30 92 26 % 3 Main2::main @ 2 (19 bytes) 31 93 27 3 Main2::main (19 bytes) 32 93 28 % 4 Main2::main @ 2 (19 bytes) 33 94 26 % 3 Main2::main @ -2 (19 bytes) made not entrant 34 95 28 % 4 Main2::main @ -2 (19 bytes) made not entrant

通过观察,我们发现name和name1函数都被进行JIT编译了,因为他们都是高热点函数,并且执行次数较多。

那么我们来看一下,如果执行次数比较少的时候,是什么情况呢?我们修改一下代码:

1public class Main2 { 2 public static void main(String[] args) throws ClassNotFoundException { 3 for (int i = 0; i < 100; i++) { // 这个地方1000000 变成了100 4 name(i); 5 } 6 } 7 8 public static void name(int k) { 9 for (int i = 0; i < k; i++) { 10 name1(i); 11 } 12 } 13 14 private static void name1(int i) { 15 i = i * 100; 16 } 17}

修改后,我们再执行,在看JIT编译函数,你会发现name和name1都不见了,这也验证了JIT是运行时,C1或者C2编译器发现热点函数,进行重新编译起到作用。

1D:\software\eclipse\eclipse-workspace_solo\TESTTT\src>java -XX:+PrintCompilation Main2 2 73 1 3 java.lang.String::hashCode (55 bytes) 3 74 2 3 java.lang.String::equals (81 bytes) 4 75 3 4 java.lang.String::charAt (29 bytes) 5 75 4 3 java.lang.String::<init> (82 bytes) 6 75 11 n 0 java.lang.System::arraycopy (native) (static) 7 77 10 4 java.lang.String::length (6 bytes) 8 77 6 3 java.lang.Character::toLowerCase (9 bytes) 9 78 7 3 java.lang.CharacterData::of (120 bytes) 10 78 8 3 java.lang.CharacterDataLatin1::toLowerCase (39 bytes) 11 79 9 3 java.lang.CharacterDataLatin1::getProperties (11 bytes) 12 79 5 3 java.util.Arrays::copyOfRange (63 bytes) 13 83 12 3 java.lang.Object::<init> (1 bytes) 14 83 13 3 java.lang.AbstractStringBuilder::ensureCapacityInternal (27 bytes) 15 84 15 3 java.lang.String::indexOf (70 bytes) 16 85 18 1 java.lang.Object::<init> (1 bytes) 17 85 12 3 java.lang.Object::<init> (1 bytes) made not entrant 18 86 14 3 java.lang.AbstractStringBuilder::append (29 bytes) 19 87 17 3 java.lang.StringBuilder::append (8 bytes) 20 88 16 3 java.io.WinNTFileSystem::isSlash (18 bytes) 21 88 19 s 3 java.lang.StringBuffer::append (13 bytes) 22 93 20 3 Main2::name1 (6 bytes)
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

P2P技术揭秘.P2P网络技术原理与典型系统开发

Modular.Java(2009.06)\.Craig.Walls.文字版.pdf:http://www.t00y.com/file/59501950(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%2Fwww.t00y.com%2Ffile%2F59501950)\More.E

Android So动态加载 优雅实现与原理分析

背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我