java queues 性能_Java性能优化要点

JITJava即时编译器

当Java执行runtime环境时,每遇到一个新的类,JIT

展开循环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:这是

内联日志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方法已经小到适合内联了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值