有人能指点我的方向吗?这可能会让我明白为什么JIT去优化我的循环?(OSR)。看起来它是由C1编译一次,然后再经过多次去优化(我可以看到几十个或上百个以开头的日志)。
这是包含重要循环的类:
@SynchronizationRequired
public class Worker implements Runnable
{
private static final byte NOT_RUNNING = 0, RUNNING = 1, SHUTDOWN = 2, FORCE_SHUTDOWN = 3;
private static final AtomicIntegerFieldUpdater<Worker> isRunningFieldUpdater =
AtomicIntegerFieldUpdater.newUpdater(Worker.class, "isRunning");
private volatile int isRunning = NOT_RUNNING;
private final Queue<FunkovConnection> tasks = new SpscUnboundedArrayQueue<>(512);
/**
* Executing tasks from queue until closed.
*/
@Override
public void run()
{
if (isRunning())
{
return;
}
while (notClosed())
{
FunkovConnection connection = tasks.poll();
if (null != connection)
{
connection.run();
}
}
if (forceShutdown())
{
setNonRunning();
return;
}
FunkovConnection connection;
while ((connection = tasks.poll()) != null)
{
connection.run();
}
setNonRunning();
}
public void submit(FunkovConnection connection)
{
tasks.add(connection);
}
/**
* Shutdowns worker after it finish processing all pending tasks on its queue
*/
public void shutdown()
{
isRunningFieldUpdater.compareAndSet(this, RUNNING, SHUTDOWN);
}
/**
* Shutdowns worker after it finish currently processing task. Pending tasks on queue are not handled
*/
public void shutdownForce()
{
isRunningFieldUpdater.compareAndSet(this, RUNNING, FORCE_SHUTDOWN);
}
private void setNonRunning()
{
isRunningFieldUpdater.set(this, NOT_RUNNING);
}
private boolean forceShutdown()
{
return isRunningFieldUpdater.get(this) == FORCE_SHUTDOWN;
}
private boolean isRunning()
{
return isRunningFieldUpdater.getAndSet(this, RUNNING) == RUNNING;
}
public boolean notClosed()
{
return isRunningFieldUpdater.get(this) == RUNNING;
}
}JIT日志:
1. <task_queued compile_id='535' compile_kind='osr' method='Worker run ()V' bytes='81' count='1' backedge_count='60416' iicount='1' osr_bci='8' level='3' stamp='0,145' comment='tiered' hot_count='60416'/>
2. <nmethod compile_id='535' compile_kind='osr' compiler='c1' level='3' entry='0x00007fabf5514ee0' size='5592' address='0x00007fabf5514c10' relocation_offset='344' insts_offset='720' stub_offset='4432' scopes_data_offset='4704' scopes_pcs_offset='5040' dependencies_offset='5552' nul_chk_table_offset='5560' oops_offset='4624' metadata_offset='4640' method='Worker run ()V' bytes='81' count='1' backedge_count='65742' iicount='1' stamp='0,146'/>
3. <deoptimized thread='132773' reason='constraint' pc='0x00007fabf5515c24' compile_id='535' compile_kind='osr' compiler='c1' level='3'>
<jvms bci='37' method='Worker run ()V' bytes='81' count='1' backedge_count='68801' iicount='1'/>
</deoptimized>
4. <deoptimized thread='132773' reason='constraint' pc='0x00007fabf5515c24' compile_id='535' compile_kind='osr' compiler='c1' level='3'>
<jvms bci='37' method='Worker run ()V' bytes='81' count='1' backedge_count='76993' iicount='1'/>
</deoptimized>
5.<deoptimized thread='132773' reason='constraint' pc='0x00007fabf5515c24' compile_id='535' compile_kind='osr' compiler='c1' level='3'>
<jvms bci='37' method='Worker run ()V' bytes='81' count='1' backedge_count='85185' iicount='1'/>
</deoptimized>
6. <deoptimized thread='132773' reason='constraint' pc='0x00007fabf5515c24' compile_id='535' compile_kind='osr' compiler='c1' level='3'>
<jvms bci='37' method='Worker run ()V' bytes='81' count='1' backedge_count='93377' iicount='1'/>
</deoptimized>这里有两个问题:
发布于 2021-02-02 00:26:15
剧透
这是一张幸运的照片,就像@apangin评论的那样。如果你想知道到底发生了什么,不要浪费时间阅读这个答案。

-回答时我的照片
尽管JIT编译器在某些情况下可能会积极地内联,但它仍然有自己的时间限制,如果这需要大量时间来完成,则不会内联。因此,方法只有在字节码大小小于35字节(默认情况下)时才有资格内联。
在您的示例中,您的方法是大小为81字节的,因此不合格:
<jvms bci='37' method='Worker run ()V' bytes='81' ...
Java性能: Scott的最终指南 是否内联一个方法的基本决定取决于它有多热以及它的大小。JVM根据内部计算确定方法是否热(即频繁调用);它不受任何可调参数的直接影响。如果一个方法因为经常被调用而有资格内联,那么只有当它的字节码大小小于325个字节(或任何被指定为-XX:MaxFreqInlineSize=N标志的方法)时,它才会内联。否则,只有当很小时,它才有资格进行内联:小于35个字节的(或任何被指定为-XX:MaxInlineSize=N标志的东西)。
为了使您的方法成为内联的-XX:MaxInlineSize=N.,可以通过命令行更改内联大小限制,指定
作为一种测试,您可以尝试指定类似-XX:MaxInlineSize=90的内容,以检查这些方法现在是否内联。
给读者--上面的建议“解决了”问题(不是真的固定的)。多么?不知道。我甚至得到了正确的答案,滴答,
附录
(我会让这个看起来很酷)
-- JVM语言的工作负载特性
Aibek S. Lukas S. Lubomír B. Andreas S. Andrej P. Yudi Z. Walter B.

发布于 2021-04-19 15:11:03
最近我在一个aarch64平台上也遇到了同样的问题。一些有趣的发现:
https://stackoverflow.com/questions/66001797
复制相似问题