首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >受jvm/ jvm影响的代码示例-选项

受jvm/ jvm影响的代码示例-选项
EN

Stack Overflow用户
提问于 2015-02-17 18:10:30
回答 1查看 616关注 0票数 4

我正在寻找代码示例,其中的结果取决于以下内容:

  • Java版本
  • 虚拟机
  • Java选项/ JVM选项

例如,将有以下代码:

代码语言:javascript
复制
Integer foo = 400;
Integer bar = 400;
System.out.println(foo == bar)

看了这段代码,很多人会猜测,它是假的,但它取决于IntegerCache.high的值,它可以用-Djava.lang.Integer.IntegerCache.high=1000进行更改

我想,有很多例子可以用内存限制来改变行为,但是还有更多意想不到的例子吗?

EN

回答 1

Stack Overflow用户

发布于 2015-02-17 20:32:55

Java版本影响:

1)看看这样的读者:

代码语言:javascript
复制
public class Reader {
   private final String input;
   private int currentPosition;
   private Pattern numberPattern = Pattern.compile(...);

   public String readNextInt() {
       return numberPattern.matcher(input.substring(currentPosition)).group();
   }
}

在早于七个版本的Java版本中,这段代码运行良好,因为String.substring()只是共享其内部缓冲区,并存储两个指向缓冲区开始/结束的指针。但是在Java 7中,这种行为被改变了,现在每个子String ()调用都会创建一个新的String对象,并带有自己的缓冲区,这会极大地影响代码的性能,特别是在较大字符串的情况下。

2)当Java1.2发布时,所有中间浮点操作只能表示为单精度或双精度,从而导致多个舍入错误。1.2JVM可以将中间结果表示为80位扩展双倍,这大大提高了精度.因此,您可以在不同的处理器和不同版本的java上观察到不同的浮点结果。

为了向后兼容或不同体系结构之间的兼容性,有严格修饰符。

3)在Java 8中,所有与反射相关的代码都经过了高度优化,因此切换到新版本将显著提高任何依赖反射的代码的性能。看看一些基准测试-- 这里

4) Java 5和JSR-133.JSR-133是一种全新的内存模型,没有前一个的缺陷。最终字段语义和易失性字段语义发生了更改。此外,Java中并发编程的许多方面也发生了变化,因此您可以预期Java 5前后多线程程序的行为完全不同。您可以阅读更多关于JSR-133 这里的内容。

5)在Java 7中更改了Mergesort实现,它会导致旧代码抛出IllegalArgumentException。阅读更多的这里

6)每个新的java发行版都引入了一些性能改进或bug修复,因此通常您可以看到一些小的改进(甚至不是,例如,在Java 8中,为了避免在堆上分配lambda而进行的严重增强的转义分析),但在很少情况下,减速也是可能的。

VM : --除了hotspot之外,我对VM不太了解,但您可以预期会有一些JIT改进/减速、不同的内存消耗和GC延迟(比如Azul,它的c4收集器和内存要求很高),甚至是静态的提前编译,比如在Excelsior中。但是,通常您知道在JVM实现之间切换时要做什么。

Java/选项:

1)偏置锁定。像-XX:+UseBiasedLocking和-XX:BiasedLockingStartupDelay=n这样的标志可以根据并发配置文件改变应用程序的性能,因此使用这些标记可以增强和损害应用程序。例如,在Azul,祖鲁,工程师只是给偏置锁定,因为不可避免的STW,当你试图撤销有偏见的锁(是的,锁撤销足够只停止两个线程,但只有全局STW的设计热点)。

2)在JVM启动时,XX:+AlwaysPreTouch标记触摸并对所有内存页进行零处理,以避免在运行时受到惩罚,并防止linux窃取您的页面。

4) -XX:+BindGCTaskThreadsToCPU现在没有在JDK8中实现,但以后可能会影响gc性能:)

5) -XX:+UseNUMA可以提高NUMA体系结构上的性能,JVM将尝试为NUMA节点划分堆。这篇文章指出,“NUMA感知分配器的性能提高了40 %”。

6) -XX:+UseCondCardMark可以帮助您在高度并发的应用程序中防止错误共享,而您并没有对此期望太高。在java中,堆在512字节区域(“卡片”)上分开,程序中的每一次写入都会导致对相应的卡片(外部对象的地址移动9)的易失性写入。因此,平均64张卡共享相同的L1缓存线。这意味着在32 32kByte (= 512 * 64)区域中的对象中写入会导致对同一缓存行的写入,这会降低应用程序的性能。-XX:+UseCondCardMark用if (card[address >> 9] == 0) card[address >> 9] = 1代替对卡片表的写入,这样可以将每个竞争的32 to区域中的易失性写入量从数百条减少到1条。

7)有许多影响GC性能的标志,但我相信您可以自己挖掘,因为在这里编写gc调优的所有建议并不有趣。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28568171

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档