《分布式Java应用:基础与实践》样章、代码、纠错、补充

《分布式Java应用:基础与实践》一书中会存在一些错误的地方,以及一些尚未深入讲解的部分,在这篇文章里会提供纠错的信息以及补充的内容的文章的链接,关于书中错误的部分,还请各位海涵和帮助指正。

样章请从此下载:
http://bluedavy.me/book/booksample.pdf

随书的代码请从此处下载:
http://bluedavy.me/book/source.zip

《分布式Java应用:基础与实践》一书中会存在一些错误的地方,以及一些尚未深入讲解的部分,在这篇文章里会提供纠错的信息以及补充的内容的文章的链接,关于书中错误的部分,还请各位海涵和帮助指正。

样章请从此下载:
http://bluedavy.me/book/booksample.pdf

随书的代码请从此处下载:
http://bluedavy.me/book/source.zip

===============纠错===============

  • 第257页 — 感谢@偶系阿萌 的反馈
    “当节点较少时,有可能会出现这些机器节点是均匀分布的现象”
    应修改为:
    “当节点较少时,有可能会出现这些机器节点是不均匀分布的现象”

  • 第41页 — 感谢dongtalk的反馈
    “各厂商在实现JDK时通常会将符合Java语言规范的源代码编译为class文件的编译器”
    应修改为:
    “各厂商在实现JDK时通常会提供将符合Java语言规范的源代码编译为class文件的编译器”

  • 第46页 — 感谢yeshucheng的反馈
    图3.4中的“Booksrap ClassLoader”应为“BootStrap ClassLoader”

  • 第68页
    图3.13用来说明Sun hotspot中可用的GC,其中旧生代可用的GC的图有错误的地方,准确来说,在Sun Hotspot V 1.6.0中并行GC应该有两种:Parallel Mark Sweep和Parallel Compacting。

  • 第71页
    “只有经历过几次Minor GC仍然存活的对象,才放入旧生代中,这个在Minor GC中存活的次数在串行和ParNew方式时可通过-XX:MaxTenuringThreshold来设置,在Parallel Scavenge时则由Hotspot根据运行状况来决定。”
    这句话准确的应为:
    “只有经历过几次Minor GC仍然存活的对象,才放入旧生代中,这个在Minor GC中存活的最大次数在串行和ParNew方式时可通过-XX:MaxTenuringThreshold来设置,但并不代表对象一定会存活MaxTenuringThreshold次才会晋升到旧生代,串行和ParNew采用一个规则在每次Minor GC后计算可存活的次数,规则为累积每个age的对象所占的内存,一直计算到占用大小超过survivor space一半的age,如计算了所有的age,均未超过则以MaxTenuringThreshold为准,否则则以age为准,在Parallel Scavenge时默认情况下由Hotspot根据运行状况来决定。”。

  • 第73页
    “并行GC在基于SurvivorRatio值划分eden space和两块survivor space的方式上和串行GC一样。”
    修正为
    “默认情况下并行GC在基于SurvivorRatio值划分eden space和两块survivor space的方式上和串行GC一样,在开启-XX:+UseAdaptiveSizePolicy后则为每次Minor GC后动态计算eden、to的大小。”

  • 第73页
    “当在Eden Space上分配内存时Eden Space空间不足,JVM即触发Minor GC的执行,也可在程序中通过System.gc的方式(可通过在启动参数中增加-XX:+DisableExplicitGC来避免程序中调用System.gc触发GC)来触发。”
    修正为
    “当在Eden Space上分配内存时Eden Space空间不足,JVM即触发Minor GC的执行,当旧生代采用并行GC时,也可在程序中通过System.gc的方式(可通过在启动参数中增加-XX:+DisableExplicitGC来避免程序中调用System.gc触发GC)来触发。”

  • 第77页 — 感谢dongtalk的反馈
    “首先将代空间划分为并行线程个数的区域(regions)”
    应修改为
    “首先将旧生代空间划分为并行线程个数的区域(regions)”

  • 第77页
    并行应为并行Compacting,书中没有介绍Parallel Mark Sweep,在后续的blog中会进行完善;

  • 第78页
    这句话是错误的:“并行是server级别机器(非32位Windows)上默认采用的GC方式,也可通过-XX:+UseParallelGC或-XX:+UseParallelOldGC来强制指定。”
    修正为
    “并行是server级别机器(非32位Windows)上默认采用的GC方式,可通过-XX:+UseParallelGC来指定使用Parallel Mark Sweep,通过-XX:+UseParallelOldGC来指定使用Parallel Compacting。”;

  • 第80页
    “CMS GC触发的条件为旧生代已使用的空间达到设定的CMSInitiatingOccupancyFraction百分比,例如默认CMSInitiatingOccupancyFraction为68%,如旧生代空间为1 000MB,那么当旧生代已使用的空间达到680MB时,CMS GC即开始执行;”
    修正为
    ”CMS GC触发的条件为旧生代已使用的空间达到设定的CMSInitiatingOccupancyFraction百分比或持久代已使用的空间达到设定的CMSInitiatingPermOccupancyFraction百分比,例如在JDK 6.0中默认值为92,如旧生代空间为1000MB,那么当旧生代已使用的空间达到920MB时,CMS GC即开始执行;“

  • 第80页
    ”持久代的GC也可采用CMS方式,方式为设置以下参数:-XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled。“
    修正为
    ”持久代的GC也可采用CMS方式,方式为设置此参数:-XX:+CMSClassUnloadingEnabled。“;

  • 第87页
    表3.1中:Server模式下旧生代和持久代GC方式准确的说应为Parallel Mark Sweep;

  • 第87页
    表3.2中:”-XX:+UseParallelGC 并行回收GC 并行GC“准确的说应为:”-XX:+UseParallelGC 并行回收GC Parallel Mark Sweep GC“;

  • 第87页
    表3.2中:“-XX:+UseParallelOldGC 并行回收GC 并行GC”准确的说应为:“-XX:+UseParallelOldGC 并行回收GC 并行Compacting GC”;

  • 第99页 — 感谢liang xie的反馈
    “如果要分析jvm堆dumap文件”
    应为:
    “如果要分析jvm堆dump文件”

  • 第112页 — 感谢liang xie的反馈
    “JDK常用package中的常用类进行分析……….,对根据需求合理地选择类会有一定的帮助”产生了重复。

  • 第113页 — 感谢libai的反馈
    ”super调用的为AbstractList的默认构造器方法….ArrayList采用的是数组的方式来存放对象“
    这段话出现了重复。

  • 第183页 — 感谢liang xie的反馈
    “在没有安装pidstat或内核版本为2.6.20以后”
    应为
    “在没有安装pidstat或内核版本为2.6.20之前”

    ===============内容补充===============
    1、说说MaxTenuringThreshold这个参数
    2、Sun JDK OOM

  • 《《分布式Java应用:基础与实践》样章、代码、纠错、补充》有153个想法

    1. 我是一名大三的学生,正在看你的书,发现自己在分布式方面是个文盲,现在终于长了点见识,对你的书真是爱不释手,吼吼…

    2. 终于出版了,17号在dangdang下的单,周一应该就可以送达,提前感谢bluedavy一声

      1. :),我更需要感谢你的支持,也希望继续关注这个贴,避免书里的错误造成了误导,如发现其他什么错误也欢迎来反馈。

    3. 第四章《集合包》部分如果能从基础数据机构方面入手,比较(有序)数组,(有序)链表和二叉树之间读取、插入、删除的性能,就相对容易一些了。

    4. 老毕同学,非常佩服你,你说到jvm内容在网上比较少,不过openjdk上面也有涉及,有些地方你还对openjdk上面进行扩充,可惜openjdk是英文的,感谢你提供了中文。整本书还是比较好的,也比较有深度。期待你下一本。

    5. 正在看,为什么卓越不卖???太讨厌当当的送券模式了,
      发现问题马上反馈,省着第二版有问题。
      113页下面有一段是重复的。。。。

      学到了很多知识谢谢bluedavy!!!

    6. 好奇问一下: 在你眼里,怎样算是一个功力深厚的java程序员 :)(除了回答像你一样)

      1. 我自己觉得…至少要对工作中涉及的Java框架、类库、JVM的实现有充分的掌握,最好是能够对os相关的部分也有相应的掌握,这样一方面是可以尽量的避免程序出现错误,另一方面是在出问题时能够很快的查出问题,解决问题的能力和速度我觉得是一个功力深厚的程序员的最明显表现。

    7. 今天下班,对照着上面做了修改,这书现在像本读书笔记,嘿嘿。
      本书第一章感觉只是轻轻点水,意犹未尽,希望以后能够再次深入。
      第三章很出彩,至于第四章,更多是性能的深入,之前有看过清华大学出版社一本介绍集合的书,如果和第四章结合一下,妙哉啊!

      深入浅出,不错。还没有看完,继续看,哈哈

    8. P72页
      2.并行回收GC(Parallel Scavenge)
      1:默认情况下Eden ,s0 ,s1 的比例划分采用的为InitialSurvivorRation ,此值默认为8 ,
      2:第二行:对应的新生代大小为 / survivo sapce

      3:那么当-Xmn设置为16M,eden space 刚为12M…..
      如果配置SurvivorRation 为8 ,那么eden space 为12.8M

      对于1:InitialSurvivorRation 值是什么比什么的比值
      对于2:没看懂什么意思
      对于3:因为没明白1,2,所以不知道这些对应的比例是什么关系,怎么算出edes space和 Survivor space

      林老师可否稍加解释下,谢谢!

    9. @fuyou
      1、InitialSurvivorRatio代表的是新生代大小/Survivor大小;
      2、就是解释的InitialSurvivorRatio;
      3、根据这个比例方式就可计算出了…

    10. 第一时间买了一本
      但有个小请求,书中列了很多网上文章的链接,这里能不能发一个类似参考的一个附页,然后最好能从这里下载到,一个个敲太痛苦了
      多为读者考虑一下吧,谢谢

    11. 56页有如下描述:
      逃逸分析是指根据运行状态来判断方法中的变量是否会被外部读取。如不会则认为此变量是逃逸的,
      —————————————
      如果变量在运行中不会被外部读取,则此变量是逃逸的。
      可以这样理解吗?

      1. 变量不会在其他线程中拿到,就可以认为这个变量是未发生逃逸的。
        例如
        User c=null;

        public void execute(){
        User a=new User();
        User b=new User();
        c=b;
        String aName=a.getName();
        }
        在这个例子中,简单分析的话,a是未发生逃逸的,b则是发生了逃逸的。
        更复杂的状况就可以演变为a再作为参数传入另外一个方法…

    12. 请教个 问题
      在命令行 直接执行 jps 后会输出本台的 vimID

      不过我现在 的这台机器不知道咋了 执行之后没有任何输出

      好奇怪 ~~~~~~~~~

    13. 说下自己的感受,书名和内容出入,感觉更应该叫《Java应用:基础与实践》

      和分布式相关东西不多,倒是Jvm和集合类讲了不少

      更像是一个平时的读书笔记的整理。

      1. 个人觉得看怎么认为分布式吧,我觉得一个应用是由多个系统组成的,就可以称为分布式,这个时候会涉及通信等知识,而大型分布式应用会涉及性能、可用性、伸缩性这些问题,虽然书中没有写的很详细,但毕竟还是提及了,至少我自己觉得还是涵盖到了一个大型的分布式Java应用应掌握的知识点,所以我自己觉得这本书的书名问题不大。

        ps: 能不能说下你觉得这个书名应该包含些什么样的内容呢,看看能不能在第二版重印的时候争取修改和增加一些内容。

    14. 个人认为 JVM 和集合的介绍可以删减或直接拿掉,有喧宾夺主的感觉。

      适当增加 一般分布式用到的技术 如 RMI,WS,JMS….等的介绍

      以及一些分布式架构

      如SOA等相关的东西,ESB等

      REST也可

      也可以增加分布式事务的实现等,技术层或业务层

      范围很广

      。。。。。。

    15. @GoingDown
      个人觉得,要编写好一个高性能、高可用的大型分布式Java应用,JVM的掌握是必须的,甚至我觉得篇幅都不够多…

      SOA、ESB等东西在书里确实只做了简单的介绍,因为这些东西如果介绍详细的内容,很容易就涉及到公司目前尚未公开的一些技术,这不是很好操作…

    16. 作为一个从业人员,感觉这本书真的是填补了相关领域的空白,而且完全同意作者JVM部分还不够的说法,至于分布式相关技术的介绍,这样的书太多了。感谢作者,正在拜读中。。。

    17. 有个疑问:45页讲初始化(Initialize)“初始化过程及执行类中的静态初始化代码、构造器代码及静态初始化”

      VM Spec 中 2.17.4 Initialization 是这样说的” Initialization of a class consists of executing its static initializers (§2.11) and the initializers for static fields (§2.9.2)
      declared in the class.”

      Inside the JVM 中是这样写的 “All implementations must initialize each class or interface on its first active use.”

      静态初始化毫无疑问只会执行一次。所以说调用new的时候会触发初始化执行是不是不够准确。

      希望bluedavy能抽时间解释一下。

    18. 看完了第一章,感觉还是挺实在的,只是有一个NIO的机制暂时未有吃透,上面除了说明就是代码,如果有个NIO的图看看该多好啊

    19. 第56页第二行,“如不会则认为该变量是逃逸的”;这里应该是“如会则认为…”吧?
      把“不会”改成“会”。方法内部定义的变量如果能够被外部访问,则该变量逃逸出本地方法。

    20. 第142页, “如执行了三次上述动作后,仍然有问题”, 是不是应该为“如执行了两次上述动作后,仍然有问题”。

    21. hi, davy. 我在某个版本的样张中,看到有这样的规划:架构层面保障(容错、监测、自愈、报警、保护措施(例如降级等),我很想了解你们在这个层面的一些经验,能不能进行分享? 请follow http://twitter.com/lynnchai , 🙂

    22. 23页。有个问题,对应的新生代大小为/survivor space,此地是否应为total space/survivor space?有些疑问

      1. 是new generation的大小/survivor space,我想没有问题,可以自己写段简单代码运行下然后用jmap -heap看下就可以确认了。

    23. 写错了,不好意思。73页。此值默认为8,对应的新生代大小为/survivor space.这句话是否应该是 ”对应的为新生代大小/survivor space“ ,要不然说不通。

    24. 在看书6.2.2及时发现故障时,有一块说的是日志记录和分析系统,个人感觉写的比较粗略,很想了解大型互联网应用中的日志系统是如何建立和维护的。或作者有什么好书推荐?

    25. 一样有点感觉jvm相关的讲的过多
      其实也不是过多,是觉得象上面说的,RMI,WS,JMS等等应该多做些介绍
      看前面还有提到,但是后面的那些章就完全深入到jvm里面了,涉及到了java本身的多线程并发讲了很多,对分布式模块间交互方面讲的很少,
      更象是java多线程应用性能调优,关于分布二字提到的太少了,意犹未尽啊⋯⋯

    26. 顺便提个建议,评论的翻页最好下面也放一个,因为你这里最新评论是在下面,看到下面的时候还需要回到上面去分页,体验不太好。。我找了半天才发现上面有个order 和newer⋯⋯

    27. p48页,findSystemClass的解释好像有点不太准确。
      原文“如未找到,则继续从BootStrap Class Loader中寻找…..”

      //ClassLoader.java JDK
      protected final Class findSystemClass(String name)
      throws ClassNotFoundException
      {
      check();
      ClassLoader system = getSystemClassLoader();
      if (system == null) {
      if (!checkName(name))
      throw new ClassNotFoundException(name);
      return findBootstrapClass(name);
      }
      return system.loadClass(name);
      }

      按照JDK源码来看,正确流程是:
      1、先获取system classloader
      2、如果获取失败(例如OSGI应用,可能不存在 system classloader),则从BootStrap ClassLoader中找(处于安全性考虑)。
      3、如果获取成功,则委托给system classloader进行加载,顺序可能是BootStrap->Ext->System

      仅供参考
      2、如果

    28. p49页 “A对象造型成另外一个A对象”
      造型-》转型

      p49页 “A对象是由两个不同的ClassLoader加载的”
      更准确的应该是:
      A对象是由两个不同的ClassLoader实例加载的

      1. 造型和转型这个我想是中文上的不同吧,maybe还是英文比较好,ClassCast…
        p49页 “A对象是由两个不同的ClassLoader加载的”
        更准确的应该是:
        A对象是由两个不同的ClassLoader实例加载的

        恩,这个同意!

    29. p47页 User-Defined Class Loader一段中有两个地方可能有点问题:

      1、“基于自定义的ClassLoader可以用于加载非classpath中(…)…”
      表述好像有点问题。自定义ClassLoader可以加载classpath中的类型,除了BootStrapClassLoader复杂加载的Java Core中的类型。因为,默认情况下,自定义ClassLoader是System ClassLoader;但如果将自定义ClassLoader的parent class loader强制设置为null时,则其父类加载器就变为BootStrap ClassLoader了。

      2、”也就是说,首先应该从Parent Class Loader中尝试进行加载,当parent中无法加载时,应再尝试从System Class Loader中开始加载,System Class Loader同样遵循此原则,在找不到的情况下会自动从其parent Class Loader中进行加载…”
      最后一句好像错了。 pareng Class Loader加载顺序在最前面,除非用户复写了loadClass逻辑,改变了Java默认的双亲委派机制。

    30. p47页 loadClass一段中,解释好像错了。

      //ClassLoader.java JDK
      protected synchronized Class loadClass(String name, boolean resolve)
      throws ClassNotFoundException
      {
      // First, check if the class has already been loaded
      Class c = findLoadedClass(name);
      if (c == null) {
      try {
      if (parent != null) {
      c = parent.loadClass(name, false);
      } else {
      c = findBootstrapClass0(name);
      }
      } catch (ClassNotFoundException e) {
      // If still not found, then invoke findClass in order
      // to find the class.
      c = findClass(name);
      }
      }
      if (resolve) {
      resolveClass(c);
      }
      return c;
      }

      原文中“如果依然没有找到,则从System Class Loader中寻找…” System Class Loader? 什么意思?

    31. p48页 “在Sun JDK中,只有当ClassLoader对象没有引用时,此ClassLoader对象加载的类才会被卸载”

      “没有引用” -》 没有被引用

    32. p50 invokespecial指令应该还负责super关键字出发的调用吧,不光是private和init两种情况。

      我做了小测试:
      void good() {
      super.hello();
      }

      对应的字节码是:
      void good();
      Code:
      0: aload_0
      1: invokespecial #15; //Method …
      4: return

    33. 面试在BlueDavy面前说BlueDavy的OSGi的Opendoc,回来之后才发现那个尴尬啊,可惜的是在终试没过,错过了跟您成为同事的机会。速度入手这本书,学习,学习…..

    34. 你好!
      我最近在读您的《分布式Java应用》,在Sun JDK类库的时候,看到ConcurrentHashMap和HashMap在多线程运行的执行时间比较时,加锁的ConcurrentHashMap却比不加锁的HashMap运行时间短、速度快。想问下作者您时候能进一步说明吗?

    35. 在P103页上描述说给方法加synchronized那里,”于是在执行其他动作前先按对象的实例ID加lock,然后在执行return i++”。
      这里感觉有问题,按这样的说法,我给这个方法加锁了,那这个ID就加锁了,那是不是在同一时间内,其它方法读或者写这个ID就会阻塞啦?但是我这样测试了是不会阻塞,结果没有阻塞。不知道是不是书的语言描述有问题,还是我理解错了?

    36. 在第64页,书上说:可以用-Xmn参数指定新生代的大小。但我在用Java命令行来查看选项时,没有看到这个选项。
      请问这是为什么?

    37. 从图书馆借的本书,发现有一处可疑之处:
      p56:“逃逸分析是指根据运行状况来判断方法中的变量是否会被外部读取。如不会则认为此变量是逃逸的。”

      ps:毕业去杭州工作,可惜不是阿里,~~~~(>_<)~~~~

    38. 毕玄,你好,我是淘宝2011招聘武汉站录取的,你是我的第一个面试官,在面试的时候,我和你提到了买了你这本书但是一直没时间看,当时你还开我的玩笑来着。现在我开始看了,但是我在p141上的第四段,关于ConcurrentHashMap的get操作的说明中有一句话我看不明白哦。
      原文是这么写的:
      put和remove操作进行时,都有可能造成HashEntry对象数组上对应位置的HashEntry发生改变。在如读操作已获取到HashEntry对象后,有一个put或remove操作完成,此时读操作尚未完成,那么这时会造成读的不一致性,但这种概率相对而言非常低。
      我的问题是这样的:
      你在第三段中不是提到了HashEntry数组时volatile类型的吗?假设在读操作中获取到HashEntry对象,此时有一个put和remove操作完成,那么在读操作中就应该可以看到更新后的数据啊。这时候读操作会造成数据不一致性的问题吗?
      春节之后就要去淘宝实习了,期待能好好的向你学习。

      1. 其实这里也不算读不一致,主要还是顺序上的问题,就是有些时候可能会出现put、remove操作先做(因为锁的原因,有可能会出现比read操作慢),但由于还没完成,此时的read操作看到的其实还是put、remove操作前的值。

    39. 想问一下:书里101页
      .读取i
      此步负责的是从main memory中读取i
      是不是应该是从working memory中读取i?谢谢哈

    40. 上周在卓越上面买的书,上面提到的错误都得到了修正,很不错的书。
      2010年12月第3次印刷的

    41. P159页,基于ConcurrentHashMap和FutureTask的改造代码中:
      MapcoonnectionPool=new ConcurrentHashMap();
      泛型类型好像是错了,应该是:
      Map<String,FutureTask>coonnectionPool=new ConcurrentHashMap<String,FutureTask>();

    42. 还是P159页基于ConcurrentHashMap和FutureTask的改造代码,虽然在改造后的代码中保证了只创建一个Connection,但是在并发情况下还是有可能会创建多个FutureTask对象吧。

    43. 跟你提个建议啊,建议在系统中添加这样一个功能,你在回复的的时候,可以同时发邮件给回复的人,这岂不是很好。

    44. 最近在拜读您的书,对书中第四章节中的集合包性能测试部分有点疑问,为何在单线程环境下List的删除操作会普遍比查找操作更费时,从实现上来看,这几乎是不可能的事情啊。

    45. 使用UseParallelGC参数并不是指在old和perm使用parallel Mark sweep,应该只是指在
      young代使用Parallel scavenge吧。
      比如在client模式下,默认都使用串行收集器
      然后使用UseParallerGC,old和perm代收集还是使用串行的吧。
      没有看到官方文档中有关于Parallel Mark Sweep的说明。

      1. @business
        :),可以自己测试下,当启用UseParallelGC后,minor gc采用的是parallel scavenge,fgc用的是parallel mark-compact,client模式下也一样。

    46. 第150页 poll(E,long,TimeUnit) 第二段,如果数组中的元素个数不为零,则从当前的对象数组中获取最后一个元素。 应该是从当前的对象数组中获取第一个元素吧。一直关注您的博客,也仔细读过您的这本书,觉得书中的小疏忽有点多啊,审稿不是很仔细。而且貌似讲分布式的寥寥无几,几乎是一笔带过。倒是JVM和java的底层讲了不少,期待您真正的分布式大作。

    47. @yangke
      第150页中,ArrayBlockingQueue方法是没有
      poll(E o, long timeout, TimeUnit unit) 这个方法的,但有poll(long timeout, TimeUnit unit) 方法。
      估计林昊为了赶速度,对比offer(E o, long timeout, TimeUnit unit) 方法,自制了一个。
      书中的
      很期待作者在分布式方面再深入一些,尽量不要在表面上,具体到实践最好不过。

    48. 你好,第56页中提到的栈上分配对象一说,是在JDK1.6或其以后版本的新特性吗?以前听说对象的分配都是在堆里分配的呀?

      1. @tangjun
        栈上分配对象这个,暂时看来目前的jdk 7里还没考虑,so在目前大部分情况下new xxx都是在eden上分配。

    49. 第47页中说道:首先应该Parent ClassLoader中尝试加载,当Parent 无法加载时,应再尝试从System ClassLoaer中进行加载。System ClassLoader同样遵循此原则,在找不到的情况下会自动从其Parent ClassLoader中进行加载。这段话不太好理解。通过看ClassLoader的loadClass方法容易理解点,呵呵,还是谢谢!

    50. 您好,正在拜读您的大作,对P2 “NIO是基于事件思想驱动的,实现上通常采用Reactor模式,从程序角度而言,当发起IO的读或写操作时,是非阻塞:”
      请问对“当发起IO的读或写操作时,是非阻塞”怎么理解?
      我看到TCP/IP + NIO的示例代码中注释写“sc.read(buffer) 为阻塞操作”。
      这是怎么回事,两处是否有矛盾的地方?

      我理解是NIO的非阻塞,指的是对server端用一个线程可以处理多个client端的请求(也就是说是非阻塞的)。而对线程本身来说read或write还是阻塞操作的。

      1. @zhanglei
        恩,没错,具体在执行IO操作的时候是阻塞的,书里表达的意思主要是程序角度,在程序角度里当使用NIO时,通常框架都会帮你将读写操作封装成异步的,而不是同步阻塞。

    51. P56中,逃逸分析的定义貌似有错误。书上是这样说的:
      逃逸分析是指根据运行状况来判断方法中的变量是否会被外部读取。如不会则认为此变量是逃逸的,
      是不是反了,如会则认为变量时逃逸的。

    52. 我是本书的一位读者,这里有个疑问想请教一下:
      在本书75页 对Times:user=0.03 sys=0.01 ,real=0.01secs 表示的是Minor Gc占用 cpu user和sys的百分比.但是有些网上的资料说是是消耗在用户态和系统态的时间(多个cpu的消耗的时间的累加,所以有可能出现user>real,real是 总时间/cpu个数),这个百分比怎么理解?

    53. 你好!我是java应用的一名忠实读者:这里冒昧的咨询个问题:在书本文件的水平伸缩方法 3 分布式文件系统谈到可以使用GFS或者HDFS来存储海量文件。这里我有个疑问:GFS我没有使用过。HDFS 正在使用。HDFS 的目的存储是为了并行计算吧?不是为了海量存储的把?单纯用HDFS来存储文件 。并发下载的速度是比较不理想的。我的观点是这样。这里只是我的疑问,而我本人开发经验不多,有什么错误。 多多指教。

      1. @Yinhex
        说到的是用于存储海量文件…可以想下,如果你要存储的文件是PB级单位的,要保证文件的不可丢失性,又要低成本,HDFS无疑是不错的选择,HDFS是为大文件而设计的,怎么合理使用这个特性来满足业务需求这是设计系统实现时需要考虑的。

    54. 非常感谢你的回答!呵呵!估计我看到那章书 同时 因为自己正在开发项目中需要用到海量存储文件的同时还要支持 大量并发访问(大文件小文件都有)。不过基于我部署的测试环境:我觉得 HDFS的并发下载文件是性能比较差的。可能我还需要继续深入研究HDFS。

    55. 看到第五章的5.1.3,讲到sar -n FULL 我的sar好像只有ALL参数,是不是版本不一样,我的是9.0.4

    56. 20011年5月第4次印刷, P72 第二段,当采用并行回收GC时,默认情况下Eden、S0、S1的比例划分采用的为InitialSurvivorRatio,此值默认为8,对应的新生代大小为/Survivor Space,

      大小为 ?? 这里好像少了

    57. 第四次印刷=>63页,3.2.1内存空间-方法区一段里,[Permanet Generation]是不是拼错了,是不是Permanent? 请确认。
      thx.

    58. P30 2.3基于Tuscany实现的SOA平台
      第一段第二行 “以下为一个基于Tuny实现发布服务和调用服务的例子”
      应该是Tuscany吧?确认下~

    59. 你好,bluedavy,我是本书的一位读者,最近在看您写的新能调优章节,有些代码在下载后发现不全,能否提供书中测试的完整的代码,比如P224中CPUNotUseEffectiveDemo.java重构后的代码,谢谢!

    发表评论

    电子邮件地址不会被公开。 必填项已用*标注


    *