标签: jvm-hotspot

Java 7至少和Java 6一样稳定吗?

我记得最初发布Java 7时,有许多建议不要将它用于任何事情,因为编译器优化中存在一些错误.这显然不仅仅是假设的.从那以后,我没有密切关注这种情况; 是否已经解决了这些问题,通常认为此时使用是安全的?

来自java.com的这个页面让我觉得它还没有准备好,但我不想过多地阅读它.如果它还不安全,是否足以-XX:-UseLoopPredicate用作VM参数?

请注意,我不仅指代特定的Lucene问题,还指Java 7的一般稳定性.Java 7是否至少与Java 6一样稳定?

java jvm-hotspot java-7

20
推荐指数
1
解决办法
2839
查看次数

CompileThreshold,Tier2CompileThreshold,Tier3CompileThreshold和Tier4CompileThreshold控制什么?

HotSpot的分层编译使用解释器,直到调用(对于方法)或迭代(对于循环)的阈值触发具有自分析的客户端编译.使用客户端编译,直到另一个调用或迭代阈值触发服务器编译.

打印HotSpot的标志使用-XX:+ TieredCompilation显示以下标志值.

intx CompileThreshold      = 10000 {pd product}        
intx Tier2CompileThreshold = 0     {product}           
intx Tier3CompileThreshold = 2000  {product}           
intx Tier4CompileThreshold = 15000 {product}           
Run Code Online (Sandbox Code Playgroud)

仅有客户端和服务器编译器的标志太多.哪些编译器由这些标志控制?如果不是客户端和服务器,其他编译器的目的是什么?

在这种情况下是否忽略CompileThreshold和Tier2CompileThreshold?触发客户端编译时Tier3CompileThreshold控制什么?触发服务器编译时Tier4CompileThreshold控制什么?

java jit jvm-hotspot compiler-flags

20
推荐指数
1
解决办法
6207
查看次数

JVM -XX:+ StringCache参数?

我最近在阅读JRE 6 [ Java VM Options ]中可用的所有JVM参数,并看到了这一点:

-XX:+ StringCache:启用常用分配字符串的缓存.

现在我一直认为Java保留了一个实习池(正确的单词?)字符串,当使用字符串连接时,它不是创建新对象,而是从这个池中提取它们.有没有人曾经使用过这个论点,或者可以解释为什么需要它?

编辑:我试图运行一个基准测试,看看这个参数是否有任何影响,并且无法让Sun JVM识别它.这与:

java version "1.6.0_11"  
Java(TM) SE Runtime Environment (build 1.6.0_11-b03)
Java HotSpot(TM) Client VM (build 11.0-b16, mixed mode,
sharing)
Run Code Online (Sandbox Code Playgroud)

所以我不确定这个论点是否有效.

java jvm jvm-hotspot jvm-arguments

19
推荐指数
2
解决办法
1万
查看次数

鼓励JVM加入GC而不是增加堆?

(注意,当我说"JVM"时,我的意思是"Hotspot",我正在运行最新的Java 1.6更新.)

示例情况:

我的JVM在-Xmx设置为1gb的情况下运行.目前,堆已经分配了500mb,其中使用了450mb.该程序需要在堆上加载另外200 MB.目前,堆中有300mb的"可收集"垃圾(我们假设它们都是最老一代的.)

在正常操作下,JVM会将堆增长到700 MB左右,并在它到达时进行垃圾收集.

在这种情况下我想要的是JVM首先gc,然后分配新的东西,这样我们最终的堆大小保持在500mb,而使用的堆在350mb.

是否有JVM参数组合可以做到这一点?

java heap jvm jvm-hotspot jvm-arguments

19
推荐指数
3
解决办法
1万
查看次数

是否有一个Java字节码优化器,可以删除无用的gotos?

问题:我有一个方法可以编译超过8000字节的Java字节码.HotSpot有一个神奇的限制,使得JIT不会超过8000字节的方法.(是的,有一个庞大的方法是合理的.这是一个标记器循环.)该方法在库中,我不想要求库的用户必须配置HotSpot来停用魔术限制.

观察:反编译字节码表明Eclipse Java Compiler生成了许多无意义的getos.(javac甚至更糟.)也就是说,有些只能从跳跃中获得.显然,跳转到goto的跳转应该直接跳到goto跳转的地方,goto应该被消除.

问题:是否有针对Java 5类文件的字节码优化器,可以使无意义的跳转链变平,然后删除不必要的getos?

编辑:我的意思是:

8698:   goto    8548
8701:   goto    0
Run Code Online (Sandbox Code Playgroud)

显然,第二个goto只能通过跳转到8701到达,这可能也是直接跳转到0.

在第二次调查中,这种可疑模式更为常见:

4257:   if_icmpne   4263
4260:   goto    8704
4263:   aload_0
Run Code Online (Sandbox Code Playgroud)

显然,人们希望编译器将"不等于"比较反转为"相等"比较,跳转到8704并消除goto.

java optimization bytecode goto jvm-hotspot

18
推荐指数
1
解决办法
1659
查看次数

方法区域和PermGen

我试图理解HotSpot JVM的内存结构,并与"方法区域"和"PermGen"空间这两个术语混淆.我提到的文档说,方法区包含类和方法的定义,包括字节代码.其他一些文档说它们存储在PermGen空间中.

那么我可以断定这两个内存区域是一样的吗?

java jvm memory-management permgen jvm-hotspot

18
推荐指数
2
解决办法
2万
查看次数

使用具有超过120GB RAM的Concurrent Mark Sweep垃圾收集器

有没有人设法在Hotspot中使用超过120GB RAM的Concurrent Mark Sweep垃圾收集器(UseConcMarkSweepGC)?

如果我将-ms和-mx设置为120G,JVM就会正常启动,但是如果我将它们设置为130G,则JVM会在启动时崩溃.JVM使用并行和G1收集器启动良好(但它们有自己的问题).

有没有人设法使用超过120GB堆的Concurrent Mark Sweep收集器?如果是这样,你有什么特别的,或者我只是在这里不走运?

来自JVM错误转储的堆栈如下:

Stack: [0x00007fbd0290d000,0x00007fbd02a0e000],  sp=0x00007fbd02a0c758,  free space=1021k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C  [libc.so.6+0x822c0]  __tls_get_addr@@GLIBC_2.3+0x822c0
V  [libjvm.so+0x389c01]      CompactibleFreeListSpace::CompactibleFreeListSpace(BlockOffsetSharedArray*, MemRegion, bool, FreeBlockDictionary::DictionaryChoice)+0xc1
V  [libjvm.so+0x3d1ae0]  ConcurrentMarkSweepGeneration::ConcurrentMarkSweepGeneration(ReservedSpace, unsigned long, int, CardTableRS*, bool, FreeBlockDictionary::DictionaryChoice)+0x100
V  [libjvm.so+0x49d922]  GenerationSpec::init(ReservedSpace, int, GenRemSet*)+0xf2
V  [libjvm.so+0x48d0b9]  GenCollectedHeap::initialize()+0x2e9
V  [libjvm.so+0x824098]  Universe::initialize_heap()+0xb8
V  [libjvm.so+0x82657d]  universe_init()+0x7d
V  [libjvm.so+0x4cf0dd]  init_globals()+0x5d
V  [libjvm.so+0x80f462]  Threads::create_vm(JavaVMInitArgs*, bool*)+0x1e2
V  [libjvm.so+0x51fac4]  JNI_CreateJavaVM+0x74
C  [libjli.so+0x31b7]  JavaMain+0x97
Run Code Online (Sandbox Code Playgroud)

我已经用Oracle(http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7175901)为此提出了一个错误,但我想知道是否有其他人见过它.

java garbage-collection jvm jvm-hotspot concurrent-mark-sweep

18
推荐指数
1
解决办法
5199
查看次数

如何编写代码以提示JVM使用向量操作?

一些相关的问题和一年之久:JVM的JIT编译器是否生成使用向量化浮点指令的代码?

前言:我试图在纯java中执行此操作(没有JNI到C++,没有GPGPU工作等等).我已经进行了分析,并且大部分处理时间来自此方法中的数学运算(可能是95%的浮点数学运算和5%的整数运算).我已经将所有Math.xxx()调用减少到足够好的近似值,因此大部分数学运算现在都是浮点数乘以一些加法.

我有一些处理音频处理的代码.我一直在进行调整,并且已经获得了巨大的收益.现在我正在研究手动循环展开以查看是否有任何好处(至少手动展开2,我看到大约25%的改进).在尝试手动展开4时(由于我展开嵌套循环的两个循环,这开始变得非常复杂)我想知道是否有任何我可以做的提示到jvm在运行时它可以使用向量操作(例如SSE2,AVX等......).音频的每个样本都可以完全独立于其他样本计算,这就是为什么我已经能够看到25%的改进(减少浮点计算的依赖性).

例如,我有4个浮点数,循环的4个展开中的每一个都有一个浮点数来保存部分计算的值.我如何声明和使用这些浮子很重要吗?如果我把它变成一个浮点数[4],它会向jvm暗示它们彼此无关,而不是浮动,浮动,浮动,浮动甚至是一类4个公共浮标?有什么我可以做的没有意义,这会杀死我的代码被矢量化的机会?

我在网上看到有关"正常"编写代码的文章,因为编译器/ jvm知道常见模式以及如何优化它们并偏离模式可能意味着更少的优化.至少在不过这种情况下,我也没有想到2展开环之多具有改进的性能,因为它没有,所以我想知道如果有什么我可以做的(或至少这样做),以帮助我机会.我知道编译器/ jvm只会变得更好所以我也要警惕做将来会伤害我的事情.

编辑为好奇:4展开的提高性能的另一个〜25%,比展开了2,所以我真的觉得向量运算会在我的情况下帮助如果JVM支持它(或者是已经使用它们).

谢谢!

java performance jvm-hotspot

18
推荐指数
1
解决办法
1538
查看次数

为什么在静态初始化器中使用并行流会导致不稳定的死锁

注意:这是不是重复,请仔细阅读题目сarefully /sf/users/241389361/报价:

真正的问题是为什么代码有时会起作用.即使没有lambdas,问题也会重现.这让我觉得可能存在JVM错误.

/sf/answers/3759645221/的评论中,我试图找出原因,为什么代码的行为从一个开始到另一个不同,并且该讨论的参与者给了我一些建议来创建一个单独的主题.

不要考虑以下源代码:

public class Test {
    static {
        System.out.println("static initializer: " + Thread.currentThread().getName());

        final long SUM = IntStream.range(0, 5)
                .parallel()
                .mapToObj(i -> {
                    System.out.println("map: " + Thread.currentThread().getName() + " " + i);
                    return i;
                })
                .sum();
    }

    public static void main(String[] args) {
        System.out.println("Finished");
    }
}
Run Code Online (Sandbox Code Playgroud)

有时(几乎总是)它会导致死锁.

输出示例:

static initializer: main
map: main 2
map: ForkJoinPool.commonPool-worker-3 4
map: ForkJoinPool.commonPool-worker-3 3
map: ForkJoinPool.commonPool-worker-2 0
Run Code Online (Sandbox Code Playgroud)

但有时它会成功完成(非常罕见):

static initializer: main
map: main 2
map: main …
Run Code Online (Sandbox Code Playgroud)

java concurrency deadlock jvm-hotspot static-initialization

18
推荐指数
1
解决办法
894
查看次数

Windows上的多线程Java应用程序的CPU使用率太低

我正在开发一个Java应用程序,用于解决一类数值优化问题-更确切地说是大规模线性编程问题。单个问题可以分解为多个较小的子问题,这些子问题可以并行解决。由于子问题多于CPU内核,因此我使用ExecutorService并将每个子问题定义为可提交给ExecutorService的Callable。解决子问题需要调用本机库-在这种情况下为线性编程求解器。

问题

我可以在Unix和具有多达44个物理内核和256g内存的Windows系统上运行该应用程序,但是在Windows上,大问题的计算时间比Linux上高一个数量级。Windows不仅需要大量内存,而且随着时间的推移,CPU利用率从开始时的25%下降到几个小时后的5%。这是Windows中任务管理器的屏幕截图:

任务管理器CPU利用率

观察结果

  • 整个问题的大型实例的解决时间从数小时到数天不等,最多消耗32g的内存(在Unix上)。子问题的解决时间在ms范围内。
  • 对于仅需几分钟即可解决的小问题,我不会遇到此问题。
  • Linux开箱即用地使用了两个套接字,而Windows要求我显式地激活BIOS中的内存交错,以便应用程序利用两个内核。但是,是否执行此操作不会对总体CPU利用率随时间的下降造成影响。
  • 当我查看VisualVM中的线程时,所有池线程都在运行,没有一个正在等待。
  • 根据VisualVM,90%的CPU时间用于本机函数调用(解决一个小的线性程序)
  • 垃圾回收不是问题,因为该应用程序不会创建和取消引用很多对象。而且,大多数内存似乎是堆外分配的。对于最大实例,Linux上4g的堆足够,而Windows上8g的堆就足够了。

我尝试过的

  • 各种JVM参数,高XMS,高元空间,UseNUMA标志和其他GC。
  • 不同的JVM(热点8、9、10、11)。
  • 不同线性编程求解器(CLP,Xpress,Cplex,Gurobi)的不同本机库。

问题

  • 是什么导致大量使用本地调用的大型多线程Java应用程序在Linux和Windows之间的性能差异?
  • 在实现方面有什么可以改变的,例如Windows,我是否应该避免使用会接收成千上万个Callable的ExecutorService来代替呢?

java java-native-interface multithreading jvm-hotspot numa

18
推荐指数
1
解决办法
369
查看次数