java性能优化--jvm中哪些方法被编译了?

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第23天,点击查看活动详情

前面一章讲解了关于编译阈值的内容,介绍了其用途和如何修改。同时也介绍了编译的部分原理,只有达到编译阈值才会触发编译,同时编译阈值会周期性减少,导致出现永远无法编译的温热代码,可以通过降低阈值的方式去优化。本章我们来学习如何找到这些温热代码,对其进行优化。

那些方法被编译了?

PrintCompilation 标志

首先我们通过jvm提供的标志,来看看有哪些方法会被编译,我们需要开启PrintCompilation标志,此标志默认是关闭的:

[root@hecs-402944 ~]# jinfo -flag PrintCompilation 13577
-XX:-PrintCompilation
复制代码

这个标志无法通过jinfo进行动态开启,所以我们需要重新启动项目指定参数:

 nohup java -XX:+PrintCompilation -jar weather-forecast-0.0.1-SNAPSHOT.jar >/dev/null &
复制代码

再次查看:

[root@hecs-402944 opt]# jinfo -flag PrintCompilation 21405
-XX:+PrintCompilation
复制代码

前面的文章讲到过,-减号表示关闭,+加号表示开启。

开启此标志,每次jvm编译一个方法,就会打印对应的日志信息:

image.png

如上所示只是部分编译内容。

其格式如下:

timestamp compilation_id attributes tiered_level method_name size deopt
编译完成时间,从0开始 编译的id,通常自增1,线程调度偶尔会乱序 代码编译的状态。有五种标志:
1)%:栈上替换编译(OSR)
2)s:同步方法
3)!:带异常处理的方法
4)b:阻塞模式时发生的编译,不会打印,后面文章会提到
5)n:分装本地方法的编译,为了便于调用本地方法
使用分层编译后才会打印,打印数字,表示分层编译级别 被编译方法名字,格式:ClassName:methodName 编译后大小(字节) 发生逆优化, made zombie 或 made not entrant

关于表格的内容,后面会有文章单独去介绍。

jstat工具

如果你不想通过重启的方式去开启编译方法的检测,那么还可以使用jstat工具。

jstat提供两个参数去查看编译信息:

  • -compiler

    [root@hecs-402944 opt]# jstat -compiler 11210
    Compiled Failed Invalid   Time   FailedType FailedMethod
        2898      1       0     4.73          1 java/net/URLClassLoader$1 run
    复制代码

    如上所示,看到参数分别是:编译完成数,编译失败数,错误数,编译类型,失败方法名。

    如果你发现自己的某个方法运行很慢,可以通过此命令查看,是否是因为编译失败引起的。

  • -printconpilation

    [root@hecs-402944 opt]# jstat -printcompilation 11210 3000
    Compiled  Size  Type Method
    2981     63    1 java/util/concurrent/locks/AbstractQueuedSynchronizer shouldParkAfterFailedAcquire
    2985     21    1 java/nio/channels/spi/AbstractSelector isOpen
    2987     36    1 java/util/concurrent/locks/AbstractQueuedSynchronizer acquireInterruptibly
    2991     98    1 java/util/concurrent/ScheduledThreadPoolExecutor$DelayedWorkQueue siftUp
    2993     24    1 java/util/concurrent/ThreadPoolExecutor$Worker tryRelease
    2997     65    1 java/util/concurrent/ScheduledThreadPoolExecutor$ScheduledFutureTask setNextRunTime
    复制代码

    如上所示,查看最近哪些方法被编译了。每3000毫秒打印一次。

猜你喜欢

转载自juejin.im/post/7110611784137965604