我想更好地了解HotSpot在运行时可能为我的Java代码生成的优化.
有没有办法看到HotSpot运行一段时间后使用的优化代码?
我有一个在低延迟环境中运行的(java)应用程序,它通常处理大约600微米(+/- 100)的指令.当然,随着我们进一步进入微秒空间,您看到的成本延迟会发生变化,现在我们已经注意到2/3的时间用于分配2个核心域对象.
基准测试已将代码的违规部分与现有引用中的对象构造完全隔离,即基本上是一组引用(每个类中约15个)和一些新的列表,但请参阅下面关于确切测量的内容的注释这里.
每个人一直需要~100微米,这对我来说是莫名其妙的,我试图找出原因.一个快速的基准测试表明,一个类似大小的对象充满了字符串需要大约2-3微米到新的,显然这种基准充满了困难,但认为它可能是有用的基线.
这里有2个Q.
请注意,所涉及的硬件是Sun X4600上的Solaris 10 x86,带有8*双核opteron @ 3.2GHz
我们看过的东西包括
任何和所有的想法赞赏
我遇到了一些关于JVM/JIT活动的参考文献,其中在编译字节码和解释字节码之间似乎有所区别.特定注释声明字节码被解释为前10000次运行并在此后编译.
"编译"和"解释"字节码有什么区别?
当jvm(在我的情况下是热点)永久地将某些代码路径编译成机器代码时,存储的机器代码在哪里?在进程内存的.text段?在进程的堆?
我不是在谈论JITing.根据我的理解,JIT将编译并运行字节码,而无需将编译代码保存在任何地方.可是你知道当JVM 是节省代码-凡在进程空间中它保存呢?
......正如评论和答案所指出的那样,我要求的一切事实上都是JIT的一部分.
编辑:
根据我在下面的评论,我特别提到的情况在这里记录为"自适应优化":http://www.oracle.com/technetwork/java/whitepaper-135217.html#hotspot
我正在阅读Java HotSpot VM Options.我见过一些有趣的虚拟机交换机,主要与字符串有关 - 这对我来说非常有价值,因为我的应用程序正在进行一些繁重的字符串操作.那些是:
-XX:+UseStringCache-XX:+UseCompressedStrings-XX:+OptimizeStringConcat我在想 - 这些开关默认是开启的吗?使用它们的真实体验是什么?他们有所作为吗?
我有一个复杂的大型多线程应用程序,我正在介绍新的功能.
我已经添加了对一块专业硬件的调用(通过供应商提供的JNI lib).然而,在调用该函数(非常快)之前,预先完成一些工作以填充发送给它的数据结构.
然而,应用程序的GC配置文件非常不稳定/不良,似乎这些填充步骤中的一些正被GC中断.这很重要,因为时间需要在第一个事件和切换到硬件资源之间保持不变或尽可能保持不变.
有没有办法说,"sychronise for GC",这些操作使得它们在停止世界GC暂停期间不会被阻止?
在RHL5.5上使用64位1.7 JDK
谢谢
我正在尝试基于具有分析信息的方法结构(由JVM提供)构建JIT策略,但我无法手动触发JIT.这个文档说我可以通过调用运行JIT java.lang.Compiler.compileClass()但是每次方法都返回false,并且java.lang.Compiler每次运行JVM时检查的属性(java.compiler)都为null.我试过OpenJDK和Oracle JVM 1.7的结果都是一样的.
但是当我观察编译统计时
$ jstat -printcompilation <PID>
Run Code Online (Sandbox Code Playgroud)
我可以看到JIT成功编译了一些符合条件的方法.
如果存在任何方式,我宁愿从java代码触发它.我也尝试在热点VM的代码中搜索,但是找不到决策和JIT开始的类和方法.
编辑:在查看更多后,我发现compilationPolicy.cpp bu仍无法找到决定所依赖的确切位置.我会期待像(简单地思考)
if(hot_count > Threshold){
compile_method(methodHandle);
}
Run Code Online (Sandbox Code Playgroud)
但相反发现了这个,
void SimpleCompPolicy::method_invocation_event(methodHandle m, JavaThread* thread) {
const int comp_level = CompLevel_highest_tier;
const int hot_count = m->invocation_count();
reset_counter_for_invocation_event(m);
const char* comment = "count";
if (is_compilation_enabled() && can_be_compiled(m)) {
nmethod* nm = m->code();
if (nm == NULL ) {
// [MY COMMENT] no check being done on hot_count in here or callee methods
CompileBroker::compile_method(m, InvocationEntryBci, …Run Code Online (Sandbox Code Playgroud) 在HotSpot JVM GC 调优指南UseGCOverheadLimit中,仅在有关 CMS 和并行 GC 的页面上提到了该选项。此外,在GC Ergonomics文档页面上,相关选项被提及GCTimeLimit,GCHeapFreeLimit就像它们仅适用于并行 GC 一样:
如果花费过多时间收集少量堆,并行垃圾收集器 (UseParallelGC) 将引发内存不足异常。为了避免这种异常,您可以增加堆的大小。您还可以设置参数 -XX:GCTimeLimit=time-limit 和 -XX:GCHeapFreeLimit=space-limit [...]
是否支持这些选项-XX:+UseG1GC?
考虑以下函数:
int foo(int[] indices) {
int[] lookup = new int[256];
fill(lookup); // populate values, not shown
int sum = 0;
for (int i : indices) {
sum += lookup[i & 0xFF]; // array access
}
return sum;
}
Run Code Online (Sandbox Code Playgroud)
现代 HotSpot 可以消除lookup[i & 0xFF]访问的边界检查吗?此访问不能越界,因为i & 0xFF范围在 0-255 之间,并且数组有 256 个元素。
java optimization performance jvm-hotspot bounds-check-elimination
如何将滚动记录保存到磁盘中,并具有最长期限?
当我的服务器出现问题时,我希望能够转储前几个小时的分析信息并对其进行分析,以了解出了什么问题。
因此,换句话说,我希望 JDK 将录音连续保存到磁盘,但删除较旧的文件/录音,以使总量保持在某个阈值(年龄或大小)以下。
为此,我有以下版本选项Oracle JDK 1.8.0_144:
-XX:+UnlockCommercialFeatures
-XX:+FlightRecorder
-XX:StartFlightRecording
name=<foo-bar>
-XX:FlightRecorderOptions
defaultrecording=true // what does this do even?
disk=true
maxage=1h // this is what I thought would solve my problem!
repository=<path-to-where-I-want-the-recording>
maxchunksize=5M
Run Code Online (Sandbox Code Playgroud)
我本以为该设置maxage=1h只会在磁盘上保留最后 1 小时的录制内容。但不是!已经过去 1 天了,文件没有被限制。
与此同时,这maxchunksize似乎起作用了。各种.jfr文件大约有5M。其中有很多这样的文件,因为没有强制执行年龄上限。
我究竟做错了什么?
java ×10
jvm-hotspot ×10
jvm ×5
performance ×3
optimization ×2
allocation ×1
g1gc ×1
jfr ×1
jit ×1
jmc ×1
latency ×1
low-level ×1
memory ×1
process ×1