前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >为何JUC中有大量代码将成员变量复制到本地变量后再操作?

为何JUC中有大量代码将成员变量复制到本地变量后再操作?

作者头像
山行AI
发布2019-06-28 16:21:49
4550
发布2019-06-28 16:21:49
举报
文章被收录于专栏:山行AI山行AI

in class String I often see member variables copied to local variables.In java.nio.Buffer I don't see that (e.g. for "position" in nextPutIndex(int nb))

在java juc和netty中有大量的将成员变量复制到本地变量再操作的情况,那么这样做到底是有没有效果呢?

关于这个问题,各个地方的说法不一。

最新的说法:

具R大说,现在的jvm已经足够智能,这种优化不需要手动来做了。

一些知名博客的说法:

1. http://cs.oswego.edu/pipermail/concurrency-interest/2011-January/007712.html 说法:
  • 不推荐一般开发人员去做特定优化;
  • 复制成员变量到本地变量能生成更小的字节码,这或许能让JIT生成更优的代码;
  • 本地变量上面带final不会带来什么性能提升,但是在软件工程角度有一些优点。
2. http://mail.openjdk.java.net/pipermail/core-libs-dev/2010-May/004165.html的说法:
  1. 这是Doug Lea大叔在JUC里面喜欢使用的代码风格;
  2. 这可能是一种非必要的极端优化;
  3. 这样做能产生更小的字节码and for low-level code it's nice to write code that's a little closer to the machine
  4. final的优化更好一些;
  5. JUC的部分算法的正确性依赖于本地变量的复制。 关于这个说法的相关的另一个问题是:
in class String I often see member variables copied to local variables.In java.nio.Buffer I don't see that (e.g. for "position" in nextPutIndex(int nb)).Now I'm wondering. From JMM (Java-Memory-Model) I learned, that jvm can hold non-volatile variables in a cache for each thread, so e.g. even in CPU register for few ones. From this knowing, I don't understand, why doing the local caching manually in String (and many other classes), instead trusting on the JVM.
3. http://cs.oswego.edu/pipermail/concurrency-interest/2013-February/010774.html 的说法:
  1. 从根本上说是由于JMM与OOP的不一致导致的;
  2. JUC里面只要一个成员变量被使用一次以上都采用了此策略;
  3. 尽管很多时候不优雅,但你更容易确认你在使用哪个值;
  4. 至于对于final型字段为何也要来一把呢?因为目前的JVM大多没法正确根据JMM避免对final的字段进行重复reload,即使一些聪明一点的jvm也一样,而对字段reload一种很重的volatile操作。

原文是:

 It's ultimately due to the fundamental mismatch between memory models and OOP :-) Just about every method in all of j.u.c adopts the policy of reading fields as locals whenever a value is used more than once. This way you are sure which value applies when. This is not often pretty, but is easier to visually verify. The surprising case is doing this even for "final" fields. This is because JVMs are not always smart enough to exploit the fine points of the JMM and not reload read final values, as they would otherwise need to do across the volatile accesses entailed in locking. Some JVMs are smarter than they used to be about this, but still not always smart enough.

总结:在性能核心部分,是有效果的(所以j.u.c和Netty大量这样搞)。 juc那么写是因为一开始就那么写(考虑到当时的jvm的现代化),而且单纯来看,local variable跟 get filed 是有性能差异,是否jvm能优化,在于是否同一个方法中重复使用了该字段,而且该jvm不会重复去reload。 讲的是其他引用类型,那写需要用 ALOAD_x 从LVT加载的引用类型。基本类型,又是final,在compile阶段就优化掉了。而且普遍来看,除非是为了追求“极致性能”,否则不建议这么做。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-06-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 开发架构二三事 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 在java juc和netty中有大量的将成员变量复制到本地变量再操作的情况,那么这样做到底是有没有效果呢?
    • 最新的说法:
      • 一些知名博客的说法:
        • 1. http://cs.oswego.edu/pipermail/concurrency-interest/2011-January/007712.html 说法:
        • 2. http://mail.openjdk.java.net/pipermail/core-libs-dev/2010-May/004165.html的说法:
        • 3. http://cs.oswego.edu/pipermail/concurrency-interest/2013-February/010774.html 的说法:
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档