我在这里找到了JVM标志.是否有更详细的解释他们到底做了什么?
我想jmap -histo
从受监控的应用程序内部以编程方式获得相当于的输出.我看到通过HotSpot诊断bean可以触发二进制堆转储,但我看不到如何获取直方图数据.可能吗 ?
据我所知,对象的哈希码通常存储在对象的标题字中,例如,它可能在HotSpot中具有以下布局:
| hash code | age | 0 | 01 |
根据HotSpotInternals -启用偏置锁定同步,标题字布局以下列方式显示:
| 0 |epoch| age | 0 | 01 |
在启用偏置锁定时,如果需要,哈哈码实际存储在何处?
基于围绕这个问题的答案的讨论,我发现了Java Hotspot优化器的一个非常奇怪的行为.观察到的行为至少可以在Oracle VM 1.7.0_17中看到,但似乎也出现在较旧的Java 6版本中.
首先,我已经意识到优化器显然意识到标准API中的某些方法是不变的并且没有副作用.执行类似循环时double x=0.5; for(double d = 0; d < Math.sin(x); d += 0.001);
,Math.sin(x)
不会为每次迭代计算表达式,但优化程序会意识到该方法Math.sin
没有相关的副作用,并且结果是不变的,只要x
在循环中没有修改.
现在我注意到,只需x
从0.5 更改为1.0就禁用了此优化.进一步的测试表明,只有当abs(x)<asin(1/sqrt(2))时才能启用优化.有没有充分的理由,我没有看到,或者是对优化条件的不必要的限制?
编辑:优化似乎在hotspot/src/share/vm/opto/subnode.cpp中实现
假设我们有3种方法:从方法1调用方法2,从方法2调用方法3.方法2和3各自大小为30字节码.另外,假设确定性方法2总是从方法1中恰好调用一次,并且方法3总是从方法2中调用一次.
如果方法2首先被内联,则方法3将直接从方法1的主体调用,并且可以依次内联.如果方法3首先内联到方法2中,则后者的大小将变为大约60个字节码,并且不能内联,因为默认MaxInlineSize
阈值是35个字节码.
HotSpot JIT以哪种顺序内联方法:自上而下或下至上?
我只想控制Java(groovy)应用程序中所有线程的堆栈大小.对于Hotspot Oracle VM,我知道有两个参数(-Xss
和XX:ThreadStackSize
).
哪个是首选?它们之间有什么区别吗?关于Open JDK 7,有人在邮件列表中询问,说明-Xss
Hotpot VM与之相同-XX:ThreadStackSize
.
关键是,我正在测量可以在我的系统上启动多少个线程.我的groovy脚本执行此操作看起来像:
int count = 0
def printCountThreads = {
println("XXX There were started $count threads.")
}
try {
while(true){
new Thread({Thread.sleep(Integer.MAX_VALUE)}).start()
count++
if(count % 1000 == 0){
printCountThreads()
}
}
} catch (Throwable e){
printCountThreads()
throw e
}
Run Code Online (Sandbox Code Playgroud)
有趣的是,我只是使用 - 减少了一些线程XX:ThreadStackSize
.我正在使用环境变量JAVA_OPTS中的不同内容启动groovy应用程序.
groovy countmax-threads.groovy
Run Code Online (Sandbox Code Playgroud)
当我将JAVA_OPTS设置为时-XX:ThreadStackSize=2m
,我会获得大约1000个启动线程,直到消耗内存为止.但是,当我使用时JAVA_OPTS='-Xss2m'
,我会得到大约32000个线程,直到出现预期的错误.所以它似乎-Xss
根本不起作用.
我在用
java版"1.8.0_05"
Java(TM)SE运行时环境(版本1.8.0_05-b13)
Java HotSpot(TM)64位服务器VM(版本25.5-b02,混合模式)
在具有四个硬件线程和大约8 GB RAM的Ubuntu 14.04 64位计算机上.
更新: …
编译以下界面:
package test;
public interface MyInterface {
public void foo();
}
Run Code Online (Sandbox Code Playgroud)
并使用javap -v -s test.MyInterface
以下方法检查已编译的代码(-s
打印成员签名):
Compiled from "MyInterface.java"
public interface test.MyInterface
SourceFile: "MyInterface.java"
minor version: 0
major version: 51
flags: ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT
Constant pool:
#1 = Class #7 // test/MyInterface
#2 = Class #8 // java/lang/Object
#3 = Utf8 foo
#4 = Utf8 ()V
#5 = Utf8 SourceFile
#6 = Utf8 MyInterface.java
#7 = Utf8 test/MyInterface
#8 = Utf8 java/lang/Object
{
public abstract void foo(); …
Run Code Online (Sandbox Code Playgroud) 我一直在阅读sun.misc.Unsafe类(openjdk6),因为我很好奇它实际引用了多少本机方法.可以理解的是,类中有大量本机方法,但我似乎无法找到它们的实现位置.
我已经通过openjdk6 repo grep了,虽然我可以找到其他类的本机方法的实现,但我找不到Unsafe的.我猜他们不是openjdk代码,而是编译为热点的一部分?
我在openjdk中查找错误的位置还是确实在热点中实现了?我们将非常感谢您对其所在地的参考.
从Java 6的某个地方开始,Hotspot JVM可以进行转义分析并在堆栈上而不是在垃圾收集堆上分配非转义对象.这导致生成的代码加速并减少垃圾收集器的压力.
Hotspot何时能够堆叠分配对象的规则是什么?换句话说,我什么时候可以依靠它来进行堆栈分配?
编辑:这个问题是重复的,但是(IMO)下面的答案比原始问题提供的答案更好.
想象一下,我定义了一个包含许多引用字段的类(而不是使用引用数组Object[]
),并在应用程序中大量实例化该类.
它是否会影响Hotspot JVM中垃圾收集器的性能,当它遍历堆来计算可达对象时?或者,对于某些JVM的内部数据结构或类元数据,它可能导致显着的额外内存消耗?或者,它是否会以某种其他方式影响应用程序的效率?
那些特定于Hotspot中的每个垃圾收集器算法的方面,或者Hotspot的机制的那些部分是否被所有垃圾收集器共享和使用?
java ×10
jvm-hotspot ×10
jvm ×7
bytecode ×1
heap ×1
heap-dump ×1
inline ×1
interface ×1
jit ×1
locking ×1
memory ×1
openjdk ×1
optimization ×1
oracle ×1
performance ×1