最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

环球快报:读Java性能权威指南(第2版)笔记08_即时编译器中

来源:博客园


(相关资料图)

1.编译阈值

1.1.一旦代码执行到一定次数,就达到了它的编译阈值,编译器就会认为它有足够的信息来编译代码

1.2.在当前的JVM中,优化阈值的意义不大

1.2.1.从JDK 7以及更早期遗留下来的

1.3.-XX:CompileThreshold=N

1.3.1.当禁用分层编译时有效

1.3.2.默认值是10 00

1.3.3.降低这个标志的值可以改善使用C2编译器的应用程序的启动时间

1.3.3.1.可能会导致一些方法被编译,而这些方法本来是永远都不会被编译的

1.4.编译器使用的计数器会随着方法和循环的执行增加计数,但是它们也会随着时间的推移而减少

1.4.1.计数器只是方法或循环最近热度的相对度量

1.4.2.有些频繁执行的代码可能永远不会被C2编译器编译,即使这个程序永远运行

1.5.-XX:Tier3InvocationThreshold=N

1.5.1.默认值200

1.5.2.让C1编译器更快地编译方法

1.6.-XX:Tier4InvocationThreshold=N

1.6.1.默认值5000

1.6.2.让C2编译器更快地编译方法

2.编译线程

2.1.调用次数更多的方法有更高的优先级

2.1.1.可以确保最重要的方法先被编译

2.2.需要编译的代码会放在编译队列中

2.2.1.队列中的代码越多,应用程序达到最佳性能需要的时间就越长

2.3.C1编译器和C2编译器有不同的队列

2.3.1.对于放在编译队列中的方法,编译是异步进行的

2.4.-XX:CICompilerCount=N

2.4.1.JVM用来处理队列的总线程数

2.4.2.三分之一(至少一个)用来处理C1编译器队列

2.4.3.剩下的线程(也是至少一个)用来处理C2编译器队列

2.4.4.如果分层编译被禁用,则只启动给定数量的C2编译器线程

2.5.在Docker容器中运行旧版本的JDK 8会导致自动优化出问题

2.5.1.需要手动将此标志设置为需要的值

2.6.可用的CPU有限,较少的线程竞争系统资源对性能有益

2.6.1.减少线程数量可以帮助提升整体吞吐量

2.6.2.代价是预热期会持续更长时间

2.7.-XX:+BackgroundCompilation

2.7.1.默认值为true

2.7.1.1.意味着队列会进行异步处理

2.7.2.设置为false

2.7.2.1.一旦方法可以被编译,想要执行它的代码就会等待,直到方法实际上完成编译,而不是继续在解释器中执行

2.8.-Xbatch

2.8.1.可以禁用后台编译

3.内联

3.1.对性能提升非常重要

3.1.1.编译器能做的最有利的优化,特别是对于属性封装良好的面向对象代码

3.1.2.不要害怕小方法,特别是getter和setter,因为它们很容易被内联

3.2.-XX:-Inline

3.2.1.默认启用

3.3.-XX:MaxFreqInlineSize=N

3.3.1.频繁内联

3.3.2.默认325字节

3.3.3.一个方法因为调用得很频繁而可以被内联,那么只有在它的字节码小于325字节时

3.4.-XX:MaxInlineSize=N

3.4.1.正常内联

3.4.2.默认35字节

3.4.3.只有在字节码小于35字节时,方法才会被内联

3.4.4.它可能会缩短测试所需的预热时间,但是不太可能对一个长期运行的应用程序产生很大影响

3.5.注意事项

3.5.1.将MaxInlineSize的值设置为大于35字节,意味着一个方法在首次调用时可能就被内联了

3.5.2.如果方法经常被调用,就说明它的性能重要得多,它总归是会被内联的(假设它小于325字节)

4.逃逸分析

4.1.编译器能够进行的最复杂的优化

4.1.1.常导致微基准测试出错

4.1.2.可以产生更快的代码,但复杂循环结构和大型方法限制了有效性

4.2.-XX:+DoEscapeAnalysis

4.2.1.默认值是true

4.2.2.C2编译器会进行大幅度的优化

4.2.3.在极少数情况下,它会出错

4.2.4.禁用这个特性可能会带来更稳定的代码

关键词: 应用程序 异步处理