《分布式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应用:基础与实践》的封面和目录

    封面:

    目录请见全文。

    封面:

    目录如下:
    第1章 分布式Java应用 1
    1.1 基于消息方式实现系统间的通信 3
    1.1.1 基于Java自身技术实现消息方式的系统间通信 3
    1.1.2 基于开源框架实现消息方式的系统间通信 10
    1.2 基于远程调用方式实现系统间的通信 14
    1.2.1 基于Java自身技术实现远程调用方式的系统间通信 14
    1.2.2 基于开源框架实现远程调用方式的系统间通信 17
    第2章 大型分布式Java应用与SOA 23
    2.1 基于SCA实现SOA平台 26
    2.2 基于ESB实现SOA平台 29
    2.3 基于Tuscany实现SOA平台 30
    2.4 基于Mule实现SOA平台 34
    第3章 深入理解JVM 39
    3.1 Java代码的执行机制 40
    3.1.1 Java源码编译机制 41
    3.1.2 类加载机制 44
    3.1.3 类执行机制 49
    3.2 JVM内存管理 63
    3.2.1 内存空间 63
    3.2.2 内存分配 65
    3.2.3 内存回收 66
    3.2.4 JVM内存状况查看方法和分析工具 92
    3.3 JVM线程资源同步及交互机制 100
    3.3.1 线程资源同步机制 100
    3.3.2 线程交互机制 104
    3.3.3 线程状态及分析 105
    第4章 分布式应用与Sun JDK类库 111
    4.1 集合包 112
    4.1.1 ArrayList 113
    4.1.2 LinkedList 116
    4.1.3 Vector 117
    4.1.4 Stack 118
    4.1.5 HashSet 119
    4.1.6 TreeSet 120
    4.1.7 HashMap 120
    4.1.8 TreeMap 123
    4.1.9 性能测试 124
    4.1.10 小结 138
    4.2 并发包(java.util.concurrent) 138
    4.2.1 ConcurrentHashMap 139
    4.2.2 CopyOnWriteArrayList 145
    4.2.3 CopyOnWriteArraySet 149
    4.2.4 ArrayBlockingQueue 149
    4.2.5 AtomicInteger 151
    4.2.6 ThreadPoolExecutor 153
    4.2.7 Executors 157
    4.2.8 FutureTask 158
    4.2.9 Semaphore 161
    4.2.10 CountDownLatch 162
    4.2.11 CyclicBarrier 163
    4.2.12 ReentrantLock 164
    4.2.13 Condition 164
    4.2.14 ReentrantReadWriteLock 165
    4.3 序列化/反序列化 167
    4.3.1 序列化 167
    4.3.2 反序列化 170
    第5章 性能调优 173
    5.1 寻找性能瓶颈 175
    5.1.1 CPU消耗分析 175
    5.1.2 文件IO消耗分析 182
    5.1.3 网络IO消耗分析 186
    5.1.4 内存消耗分析 187
    5.1.5 程序执行慢原因分析 191
    5.2 调优 192
    5.2.1 JVM调优 192
    5.2.2 程序调优 202
    5.2.5 对于资源消耗不多,但程序执行慢的情况 214
    第6章 构建高可用的系统 227
    6.1 避免系统中出现单点 228
    6.1.1 负载均衡技术 228
    6.1.2 热备 236
    6.2 提高应用自身的可用性 238
    6.2.1 尽可能地避免故障 239
    6.2.2 及时发现故障 246
    6.2.3 及时处理故障 248
    6.2.4 访问量及数据量不断上涨的应对策略 249
    第7章 构建可伸缩的系统 251
    7.1 垂直伸缩 252
    7.1.1 支撑高访问量 252
    7.1.2 支撑大数据量 254
    7.1.3 提升计算能力 254
    7.2 水平伸缩 254
    7.2.1 支撑高访问量 254
    7.2.2 支撑大数据量 264
    7.2.3 提升计算能力 266