java性能优化方案_Java性能优化要点
Java性能優化要點
本文介紹如何通過以下幾點從Java中擠壓出性能,該大部分經驗來自于Netty作者。
JITJava即時編譯器
當Java執行runtime環境時,每遇到一個新的類,JIT編譯器在此時就會針對這個類別進行編譯(compile)被優化成相當精簡的原生型指令碼(native code),會做一下工作:
展開循環loop-unrolling
重新安排代碼
移除同步synchronized
優化鎖
內聯熱點方法
首先,JIT會展開我們代碼中的循環語句,所以,我們編碼時盡量注意不要在關鍵熱點部分編寫讓JIT難于展開的循環語句。
JIT比較難以展開的循環語句如下:
int i = 0;
for (;;) {
if (array.length == i) {
break;
}
doSomething(array[i++]);
}
這種for循環雖然編寫方便,但是JIT不喜歡,下面循環則易于JIT展開:
int i = 0;
for (int i = 0; i < array.length; i++) {
doSomething(array[i]);
}
其次,JIT會內聯一些熱點小方法代碼,這些小方法缺省差不多是325字節。比如下面是普通代碼:
public void methodA() {
... // Do some work A
methodB();
}
private void methodB() {
... // Do some more work B
}
JIT會將methodB內聯合并到methodA中
//采取methodB內聯到到methodA
public void methodA() {
... // Do some work A
... // Do some more work B
}
可以通過下面的Java運行配置記錄檢測內聯:
java
-XX:+PrintCompilation
-XX:+UnlockDiagnosticVMOptions
-XX:+PrintInlining
.... > inline.log
PrintCompilation:當JIT編譯發生輸出打印
UnlockDiagnosticVMOptions:這是標識 -XX:+PrintInlining需要的
-XX:+PrintInlining :當方法被內聯后打印出來
內聯日志inline.log效果如下:
@ 42 io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe::read (191 bytes) inline (hot) (這表示方法hot被內聯了)
@ 42 io.netty.channel.nio.AbstractNioMessageChannel$NioMessageUnsafe::read (327 bytes) hot method too big (但是方法hot用于內聯太大了)
@ 4 io.netty.channel.socket.nio.NioSocketChannel::config (5 bytes) inline (hot)
@ 1 io.netty.channel.socket.nio.NioSocketChannel::config (5 bytes) inline (hot)
@ 12 io.netty.channel.AbstractChannel::pipeline (5 bytes) inline (hot)
我們編碼時對于熱點方法不要編寫對內聯太大的方法,如下面read方法:
private final class NioMessageUnsafe extends AbstractNioUnsafe {
public void read() {
final SelectionKey key = selectionKey();
if (!config().isAutoRead()) {
int interestOps = key.interestOps();
if ((interestOps & readInterestOp) != 0) {
// only remove readInterestOp if needed
key.interestOps(interestOps & ~readInterestOp);
}
}
... // rest of the method
}
...
}
分解出read()方法一部分代碼到新的方法中:
private final class NioMessageUnsafe extends AbstractNioUnsafe {
public void read() {
if (!config().isAutoRead()) {
removeReadOp();
}
private void removeReadOp() {
SelectionKey key = selectionKey();
int interestOps = key.interestOps();
if ((interestOps & readInterestOp) != 0) {
// only remove readInterestOp if needed
key.interestOps(interestOps & ~readInterestOp);
}
}
... // rest of the method
}
...
注意到read方法從原來多行已經變成了簡單幾行,這時我們再看看JIT的內聯日志:
@ 42 io.netty.channel.nio.AbstractNioMessageChannel$NioMessageUnsafe::read (288 bytes) inline (hot)
只有一行輸出,說明read方法已經小到適合內聯了。
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的java性能优化方案_Java性能优化要点的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 全志android启动串口无打印,CSK
- 下一篇: linux创建文件后会自动删除,linu