Java问题定位技术 2009 年 7 月 19 日 版权所有 目 录 1 目 录 1 Java线程堆栈分析 1 1.1 如何输出线程堆栈? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.2 如何解读线程堆栈? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.2.1 线程的解读 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.2.2 锁的解读 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 1.2.3 线程状态的解读 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 1.3 如何借助线程堆栈进行问题分析? . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 1.3.1 线程死锁分析 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 1.3.2 Java代码死循环等导致的CPU过高分析 . . . . . . . . . . . . . . . . . . . . 29 1.3.3 高消耗CPU代码的常用分析方法 . . . . . . . . . . . . . . . . . . . . . . . . 31 1.3.4 资源不足等导致的性能下降分析 . . . . . . . . . . . . . . . . . . . . . . . . 34 1.3.5 线程不退出导致的系统挂死分析 . . . . . . . . . . . . . . . . . . . . . . . . 36 1.3.6 多个锁导致的锁链分析 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 1.3.7 通过线程堆栈进行性能瓶颈分析 . . . . . . . . . . . . . . . . . . . . . . . . 38 1.3.8 线程堆栈不能分析什么问题? . . . . . . . . . . . . . . . . . . . . . . . . . 38 2 通过Java线程堆栈进行性能瓶颈分析 39 2.1 常见的性能瓶颈 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 2.2 性能瓶颈分析的手段和工具 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 2.2.1 如何去模拟,发现性能瓶颈?. . . . . . . . . . . . . . . . . . . . . . . . . . 44 2.2.2 如何通过线程堆栈识别性能瓶颈?. . . . . . . . . . . . . . . . . . . . . . . 45 2.2.3 其它提高性能的方法. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 2.2.4 性能调优的终结条件. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 2.2.5 性能调优工具 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 2.2.6 跟性能相关的JVM参数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 2.3 性能分析的手段总结 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 2.3.1 借助操作系统提供的CPU统计工具 . . . . . . . . . . . . . . . . . . . . . . 49 2.3.2 通过Java线程堆栈进行性能瓶颈分析 . . . . . . . . . . . . . . . . . . . . . 50 2.3.3 runhprof . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 2.3.4 JProfiler、JBuilder等工具 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 2.3.5 手工打印时间戳 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 3 Java内存泄漏分析和堆内存设置 52 3.1 Java内存泄漏的背景知识 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 3.1.1 Java对象的size(32位平台). . . . . . . . . . . . . . . . . . . . . . . . . . . 54 3.1.2 Java对象及其引用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 3.1.3 虚拟机自动垃圾回收机制 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 2 目 录 3.1.4 如何告诉虚拟机不再需要这块内存? . . . . . . . . . . . . . . . . . . . . . 59 3.1.5 将对象设为null就可以避免内存泄漏吗? . . . . . . . . . . . . . . . . . . . 63 3.1.6 JVM内存类型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 3.2 Java内存泄漏的症状 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 3.2.1 为什么会发生OOM(OutOfMemroy) 问题? . . . . . . . . . . . . . . . . . . 70 3.2.2 Java内存泄漏的症状 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 3.3 Java内存泄漏的定位和分析 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 3.3.1 堆内存泄漏定位 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 3.3.2 本地内存泄漏的定位. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 3.3.3 Perm内存泄漏精确定位 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 3.3.4 真实环境下内存泄漏的定位(生僻场合下的内存泄漏定位) . . . . . . . . 79 3.4 Java堆内存泄漏的解决 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 3.5 java内存和垃圾回收设置 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 3.5.1 堆内存的设置原则 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 3.5.2 在32位下如何设置堆内存? . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 3.5.3 特殊场合下JVM参数调优 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 3.5.4 Java 完全垃圾回收 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 3.5.5 top陷阱:top真得能告诉你系统是否存在内存泄漏吗? . . . . . . . . . . . 84 3.5.6 实时虚拟机 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 3.6 关于JavaScript的内存泄漏 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 4 关于并发和多线程 89 4.1 在什么情况下需要加锁? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 4.2 如何加锁? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 4.3 多线程编程中易犯的错误 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 4.4 i++这种仅有原子操作是否需要同步保护 . . . . . . . . . . . . . . . . . . . . . . . 92 4.5 进程线程多,是否就意味着我的程序可以获得更多的CPU? . . . . . . . . . . . . 92 4.6 线程的数量一般设为多少比较合理? . . . . . . . . . . . . . . . . . . . . . . . . . 93 4.7 关于线程池 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 4.8 notify和wait的组合. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 4.9 线程的阻塞 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 4.10 Java线程的优先级 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 4.11 关于多线程的一些错误观点 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 5 幽灵代码 101 5.1 异常退出幽灵代码 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 5.1.1 异常退出幽灵代码导致的资源泄漏 . . . . . . . . . . . . . . . . . . . . . . 104 5.2 wait()与循环 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 5.3 Double-Checked Locking单例模式 . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 5.4 另一种异常陷阱-连续的关键接口调用 . . . . . . . . . . . . . . . . . . . . . . . . . 108 目 录 3 6 常见的Java泥潭 110 6.1 不稳定的Runtime.getRuntime().exec() . . . . . . . . . . . . . . . . . . . . . . . . . 110 6.2 JDK自带的几个Timer的适用场合 . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 6.2.1 java.util.Timer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 6.2.2 java.swing.Timer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127 6.3 池的合理设计. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128 6.3.1 对象池 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128 6.3.2 线程池 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 6.3.3 连接池 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 6.4 JDK1.5线程池的陷阱 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 6.5 Timer的使用陷阱 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 7 JVM 132 7.1 java运行期参数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 7.2 java -X扩展运行参数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 7.3 关于JIT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 7.4 -Xrunhprof . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144 7.4.1 Java虚拟机运行期剖析接口介绍 . . . . . . . . . . . . . . . . . . . . . . . . 145 7.4.2 运行虚拟机期剖析器代理的原理及HProf代理的使用 . . . . . . . . . . . . 146 7.4.3 信息分析 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146 7.5 正确的视角看虚拟机 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152 8 关于字符集与编码 153 8.1 字符集 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154 8.2 编码 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154 8.3 Unicode和UTF-8的关系 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155 8.4 编码的识别 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156 8.5 关于编码的转换 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156 9 常用的工具 158 9.1 远程调试 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158 9.2 Java自带工具 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158 9.2.1 jconsole . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158 9.2.2 jstack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158 9.3 Unix下的进行分析利器proc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158 9.3.1 pstack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158 9.3.2 pfiles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159 9.3.3 pldd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160 9.3.4 pmap. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 9.3.5 ptree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162 4 目 录 9.3.6 pwdx . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162 9.3.7 plimit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162 9.4 Unix下的进程统计工具prstat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162 9.5 Unix下的剖析工具truss/strace/dtrace/sotrace . . . . . . . . . . . . . . . . . . . . 164 9.6 网络工具 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164 9.6.1 路由跟踪命令traceroute/tracert . . . . . . . . . . . . . . . . . . . . . . . . 164 9.7 swap交换分区管理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164 9.8 其它 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164 10 Java最佳实践 165 10.1 J2EE的潜在难点和最佳实践 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 10.1.1 架构上的问题 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 10.1.2 关于Servlet技巧 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167 10.2 Java应用程序的基本准则 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168 10.3 消息系统的设计模型和关键点 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169 10.3.1 设计模型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169 10.3.2 其它设计关键点 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174 11 关于数据库 175 11.1 关于数据库表死锁与锁表的问题 . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 11.1.1 关于表死锁 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 11.1.2 关于锁表 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176 11.2 关于数据库SQL的性能 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178 11.2.1 union语句 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178 11.3 关于高性能场合下数据库的设计模式 . . . . . . . . . . . . . . . . . . . . . . . . 179 11.4 必须使用事务吗? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180 11.5 确保Java代码不要依赖于数据库表字段的顺序 . . . . . . . . . . . . . . . . . . . 180 11.6 一种更简单的逻辑与数据分析-Named SQL . . . . . . . . . . . . . . . . . . . . . 180 12 工程实践 181 12.1 在高端机器上,一个JVM好还是多个JVM好? . . . . . . . . . . . . . . . . . . . 181 12.2 关于Java进程监控-watchdog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181 12.2.1 如何检测系统异常 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181 12.3 关于class Loader . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182 12.4 关于负载控制-动态过负荷还是静态过负荷? . . . . . . . . . . . . . . . . . . . . . 182 12.5 机器设多个IP的原理?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183 12.6 关于日志 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184 12.6.1 关于java日志的几大恶劣设计 . . . . . . . . . . . . . . . . . . . . . . . . . 184 12.6.2 什么是好的日志?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185 12.7 异常处理的原则? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186 目 录 5 12.8 基于限制的系统部署/设计. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186 12.9 String的值为什么不能改变? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187 12.10 系统出现问题需要收集的信息 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187 12.11 Web Failover集群的方案 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187 12.12 关于可靠性设计 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189 12.13 如何实现JVM Shutdown钩子函数?. . . . . . . . . . . . . . . . . . . . . . . . . 190 12.14 如何截取输出流? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191 12.15 Linux下如何将进程绑定在特定的CPU上运行? . . . . . . . . . . . . . . . . . . 191 12.16 关于Java和C++的互通 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192 12.16.1 Java代码中调用C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192 12.16.2 C++代码中调用Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193 13 常见的案例 194 13.1 Too many open files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194 13.2 java.lang.StackOverflowError . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196 13.3 java.net.SocketException: Broken pipe . . . . . . . . . . . . . . . . . . . . . . . . 196 13.4 HashMap的ConcurrentModificationException . . . . . . . . . . . . . . . . . . . . 197 13.5 多线程场合下HashMap导致的死循环 . . . . . . . . . . . . . . . . . . . . . . . . 198 13.6 Web系统吊死(挂死)的定位思路 . . . . . . . . . . . . . . . . . . . . . . . . . . 200 13.7 基于消息系统(如sip)吊死的定位思路 . . . . . . . . . . . . . . . . . . . . . . . 202 13.8 多线程读写socket导致的数据混乱 . . . . . . . . . . . . . . . . . . . . . . . . . . 202 13.9 关于CPU过高问题的定位思路 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204 13.10 系统运行越来越慢的定位思路 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206 13.11 系统挂死问题的定位思路. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207 13.12 关于线程死亡/线程跑飞 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208 13.13 关于虚拟机Core Dump . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210 13.14 系统运行运行越来越慢问题的定位思路 . . . . . . . . . . . . . . . . . . . . . . 212 13.15 代码GC导致的性能低下 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212 13.16 java.lang.OutOfMemoryError: unable to create new native thread . . . . . . . . 213 13.17 java.lang.OutOfMemoryError: PermGen space . . . . . . . . . . . . . . . . . . . 213 13.18 java.lang.OutOfMemoryError: Java heap space . . . . . . . . . . . . . . . . . . . 213 13.19 Connection Pool exhausted . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213 13.20 系统时间更改导致的系统无法正常工作 . . . . . . . . . . . . . . . . . . . . . . 214 13.21 瞬间内存泄露的定位思路. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216 13.22 第三方系统能力分析 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216 13.23 系统性能过低 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218 13.24 病灶转移-Java程序内存溢出(OutOfMemory)导致的数据库锁表 . . . . . . . . . 219 13.25 AIX下如何定位IO 100%的问题? . . . . . . . . . . . . . . . . . . . . . . . . . . 219 13.26 高性能UDP程序 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220 6 目 录 A JProfiler内存泄漏精确定位 221 B SUN JDK自带故障定位 226 B.1 SUN JDK命令行选项 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226 B.1.1 诊断工具和选项 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226 B.2 诊断工具详细介绍 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228 B.2.1 HPROF - Heap Profiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228 B.2.2 Java VisualVM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233 B.2.3 JConsole Utility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234 B.2.4 jdb Utility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236 B.2.5 jhat Utility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238 B.2.6 jinfo Utility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241 B.2.7 jmap Utility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243 B.2.8 jps Utility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248 B.2.9 jrunscript Utility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249 B.2.10 jsadebugd Daemon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249 B.2.11 jstack Utility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249 B.2.12 jstat Utility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252 B.2.13 jstatd Daemon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254 B.2.14 visualgc Tool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255 B.2.15 Ctrl-Break Handler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255 B.2.16 操作系统工具 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258 B.3 内存泄漏问题定位 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259 B.3.1 Meaning of OutOfMemoryError . . . . . . . . . . . . . . . . . . . . . . . . 259 B.3.2 Java代码中的内存泄漏诊断 . . . . . . . . . . . . . . . . . . . . . . . . . . 262 B.4 Troubleshooting System Crashes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269 B.4.1 Sample Crashes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269 B.4.2 Finding a Workaround . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273 B.5 Fatal Error Log. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277 B.5.1 Location of Fatal Error Log . . . . . . . . . . . . . . . . . . . . . . . . . . . 278 B.5.2 Description of Fatal Error Log . . . . . . . . . . . . . . . . . . . . . . . . . 278 B.5.3 Header Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279 B.5.4 Thread Section Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281 B.5.5 Process Section Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283 C 在Solaris下,查找占用指定的端口的进程 291 D 如何在solaris下面分析IO瓶颈? 292 E AIX操作系统下,32位进程的最大内存占有情况 292 表格目录 7 F 关于TCP/IP 293 G windows 2003/XP下,一个端口可以多个监听 293 H Suse9.0下,线程创建的数量和堆内存/永久内存的关系 295 I JConsole 296 J gcviewer 297 K IBM JDK下定位引起CoreDump的JIT方法 297 L 如何解读Java Core 文件? 298 L.1 SUN JDK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298 L.2 IBM JDK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298 M 几个奇怪的现象 298 M.1 等锁的线程也可以处于runnable状态? . . . . . . . . . . . . . . . . . . . . . . . . 298 M.2 没锁的也可以waiting for? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298 N 感谢TEX 300 表格目录 1 Java线程和本地线程的映射关系 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 2 JRE 1.4.2 Windows上的对象的大小 . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 3 Unicode与UTF-8的映射关系 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155 4 Linux下工具列表 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258 5 windows下工具列表 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259 6 Solaris下工具列表 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260 7 Thread Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280 8 Thread States . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281 9 VM States . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284 10 SPARC Features. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290 11 Intel/IA32 Features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290 12 AMD64/EM64T Features. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290 13 Linux下线程创建的数量和堆内存/永久内存的关系 . . . . . . . . . . . . . . . . . 296 14 Hibernate与JDBC的对比. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301 8 插图目录 插图目录 1 本地线程和Java线程的映射 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 2 含有wait(5000)的代码段锁的占用情况 . . . . . . . . . . . . . . . . . . . . . . . . . 14 3 含有sleep(5000)的代码段锁的占用情况 . . . . . . . . . . . . . . . . . . . . . . . . . 15 4 线程死锁 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 5 性能好和差的程序CPU利用率曲线对比 . . . . . . . . . . . . . . . . . . . . . . . . . 39 6 总的性能决定于最差的那一段的能力 . . . . . . . . . . . . . . . . . . . . . . . . . . 44 7 性能调优的过程 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 8 引用关系映射图(一) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 9 引用关系映射图(二) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 10 引用关系映射图(三) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 11 引用关系映射图(四) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 12 根集 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 13 引用关系映射图(五) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 14 引用关系映射图(六) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 15 引用关系映射图(七) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 16 引用关系映射图(八) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 17 引用关系映射图(九) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63 18 引用关系映射图(十) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 19 设为null的对象引用图 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 20 从hashmap移去对象的对象引用图 . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 21 将指向hashmap对象的的引用只能置空的对象引用图 . . . . . . . . . . . . . . . . 67 22 操作系统下的进程 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 23 Java进程的内存占用情况 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 24 堆内存过大会直接挤压本地内存的大小 . . . . . . . . . . . . . . . . . . . . . . . . 83 25 并行垃圾回收 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 26 并发垃圾回收 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 27 非实时虚拟机的垃圾回收占用时间 . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 28 实时虚拟机的垃圾回收占用时间 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 29 链表添加一个元素 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 30 并发存取同一个链表 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 31 单线程下CPU的使用情况 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 32 多线程下CPU的使用情况 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 33 Double-Checked Locking单例模式多线程场合下可能的执行时序 . . . . . . . . . . 108 34 JIT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 35 Session Bean Facade . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 36 MVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 37 基于servlet的MVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166 插图目录 9 38 基于EJB的MVC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166 39 接收消息模型(NIO) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169 40 发送消息模型(NIO) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169 41 表死锁 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 42 不加保护的消息发送 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202 43 加保护的消息发送 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203 44 使用JProfile进行内存泄漏定位-找到内存泄漏的对象 . . . . . . . . . . . . . . . . 222 45 使用JProfile进行内存泄漏定位-找到泄漏对象的分配树 . . . . . . . . . . . . . . 224 46 使用JProfile进行内存泄漏定位-指定对应类的对象分配树 . . . . . . . . . . . . . 224 47 使用JProfile进行内存泄漏定位-泄漏对象的分配树 . . . . . . . . . . . . . . . . . 225 48 曲线 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302 49 测试 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302 50 This is a box. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303