在HotSpot JVM GC 调优指南UseGCOverheadLimit中,仅在有关 CMS 和并行 GC 的页面上提到了该选项。此外,在GC Ergonomics文档页面上,相关选项被提及GCTimeLimit,GCHeapFreeLimit就像它们仅适用于并行 GC 一样:
如果花费过多时间收集少量堆,并行垃圾收集器 (UseParallelGC) 将引发内存不足异常。为了避免这种异常,您可以增加堆的大小。您还可以设置参数 -XX:GCTimeLimit=time-limit 和 -XX:GCHeapFreeLimit=space-limit [...]
是否支持这些选项-XX:+UseG1GC?
我刚刚阅读了 Java Magazine 文章Loop Unrolling。作者在那里演示了for带有int计数器的简单循环是通过循环展开优化编译的:
private long intStride1()
{
long sum = 0;
for (int i = 0; i < MAX; i += 1)
{
sum += data[i];
}
return sum;
}
Run Code Online (Sandbox Code Playgroud)
但是,他们随后通过将计数器类型切换为 来显示一切都发生了变化long:
private long longStride1()
{
long sum = 0;
for (long l = 0; l < MAX; l++)
{
sum += data[(int) l];
}
return sum;
}
Run Code Online (Sandbox Code Playgroud)
这会通过以下方式更改输出程序集:
这会显着降低吞吐量性能。
为什么 64 位 HotSpot VM 不为long计数器执行循环展开?为什么第二种情况需要安全点,而第一种情况不需要?
考虑以下函数:
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 6更新45中运行的JBoss应用程序服务器.我们遇到了我们最有可能自己介绍的OutOfMemoryErrors.我们想分析那些并想要创建堆转储.这失败,下面有例外.
谷歌搜索和搜索stackoverflow对我没有多大帮助,有没有人知道如何从这台机器获得堆转储?
谢谢!
马丁
例外是:
C:\>"d:\Program Files\Java\bin\"jmap -F "-dump:format=b,file=D:\heapdumps\20130620_085902_heap.dump" 1832
Attaching to process ID 1832, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 20.45-b01
Dumping heap to D:\heapdumps\20130620_085902_heap.dump ...
Exception in thread "main" java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at sun.tools.jmap.JMap.runTool(JMap.java:179)
at sun.tools.jmap.JMap.main(JMap.java:110)
Caused by: sun.jvm.hotspot.debugger.DebuggerException: Windbg Error: ReadVirtual failed!
at sun.jvm.hotspot.debugger.windbg.WindbgDebuggerLocal.readBytesFromProcess0(Native Method)
at sun.jvm.hotspot.debugger.windbg.WindbgDebuggerLocal.readBytesFromProcess(WindbgDebuggerLocal.java:485)
at sun.jvm.hotspot.debugger.DebuggerBase$Fetcher.fetchPage(DebuggerBase.java:76)
at sun.jvm.hotspot.debugger.PageCache.getPage(PageCache.java:178)
at sun.jvm.hotspot.debugger.PageCache.getInt(PageCache.java:96)
at sun.jvm.hotspot.debugger.DebuggerBase.readCInteger(DebuggerBase.java:355)
at sun.jvm.hotspot.debugger.DebuggerBase.readCompOopAddressValue(DebuggerBase.java:459)
at sun.jvm.hotspot.debugger.windbg.WindbgDebuggerLocal.readCompOopHandle(WindbgDebuggerLocal.java:332)
at sun.jvm.hotspot.debugger.windbg.WindbgAddress.getCompOopHandleAt(WindbgAddress.java:122)
at sun.jvm.hotspot.oops.Oop.getKlassForOopHandle(Oop.java:235)
at …Run Code Online (Sandbox Code Playgroud) 当我阅读"Scala in depth"一书时,它提到HotSpot编译器有几个重要的功能,其中之一就是"动态去优化":
事实上,它能够确定优化是否不会提高性能并撤消优化,从而允许其他优化应用
似乎HotSpot会尝试各种"优化",并选择其中最好的一个.
但我不是很了解它.这里的"优化"是否全部由HotSpot提供?我的意思是程序员经常尝试用一些技巧来优化代码,HotSpot会处理它们吗?
HotSpot会尝试任何常见的"优化"吗?
我想知道是否可以在不更改应用程序代码的情况下记录JVM级别发生的每个异常?每个例外我都是指捕获和未捕获的异常...我想稍后分析这些日志并按异常类型(类)对它们进行分组,并简单地按类型计算异常.我正在使用HotSpot;)
也许更聪明的为什么这样做?例如,任何免费的探查器(YourKit有它,但它不是免费的)?我认为JRockit在管理控制台中有异常计数器,但是看不到HotSpot的类似内容.
关于JLS ch17 线程和锁,它说"如果一个动作发生在另一个之前,那么第一个动作在第二个之前可见并且在第二个之前被命令"; 我想知道:
(1)说"之前订购"的真正含义是什么?因为即使action_a发生在action_b之前,action_a也可以在action_b之后的某些实现中执行,对吧?
(2)如果action_a发生在action_b之前,是否意味着action_a绝不能看到action_b?或者action_a可能会看到或看不到action_b?
(3)如果action_a没有发生 - 在action_b之前,而action_b没有发生 - 在action_a之前,是否意味着action_a可能会看到或看不到action_b?
(4)之前没有任何循环发生,对吧?
任何答案将不胜感激:)
为什么不可能创建一个max int size的数组?
int i = 2147483647;
int[] array = new int[i];
Run Code Online (Sandbox Code Playgroud)
我找到了这个解释:
通过32位整数访问Java数组,最大理论数组大小为2147483647个元素.
但是你可以看到我的代码不起作用.创建一个大小的数组也是不可能的
new int[Integer.MAX_VALUE - 5];
Run Code Online (Sandbox Code Playgroud)
PS
为什么-5呢?
使用Collections.emptyList()或空是否存在性能差异ArrayList,尤其是在使用JIT编译器时?
我可以想象 - 例如 - JIT编译器不执行内联或静态方法调用,因为执行的方法取决于类型.
编辑
我知道Collections.emptyList()返回一个不可变列表,ArrayList而是可变对象.
我的意思是,如果我将一个或另一个作为参数传递给方法,并且该方法不修改列表,那么是否限制了JIT编译器优化方法的可能性?
一个简单的例子(只是为了澄清我的意思):
int sum(List<Integer> list)
{
int sum = 0;
for(int i=0;i<list.size();++i)
sum += list.get(i);
return sum;
}
Run Code Online (Sandbox Code Playgroud)
如果我只使用ArrayListJIT编译器调用此方法可以内联ArrayList.get().如果我也用Collections.empty()它打电话是不可能的.
那是对的吗?
java ×10
jvm-hotspot ×10
jvm ×5
jit ×2
optimization ×2
performance ×2
g1gc ×1
java-6 ×1
jboss ×1
jboss7.x ×1
jfr ×1
jmc ×1