- JDK 1.6 微型HTTP服务器API?
- JDK Plug 闭源包?
- 2011年,已经不再需要了?
- Core i5 / 4GB内存,编译JDK大概需要半个小时?——还是很快的嘛
- JVM运行时数据区:
- 方法区
- 运行时常量池
- 虚拟机栈
- Native方法区
- 堆
- 程序计数器(?)
- 方法区
- 堆溢出:-Xms -Xmx -XX:+HeapDumpOnOutOfMemoryError
- 栈溢出:-Xss
- 运行时常量池溢出:-XX:PermSize -XX:MaxPermSize
- 方法区溢出
- 使用CGLib测试:new Enhancer().setCallback(new MethodInterceptor(){...
- 本机直接内存溢出:-XX:MaxDirectMemorySize
- JDK 1.4 NIO DirectByteBuffer
- Unsafe.class.getDeclaredFields()[0].get(null) -> .allocateMemory(_1MB);
- 引用计数
- 根搜索(没有引用链则认为是‘不可达’)——解决了循环引用的问题
- F-Queue
- 一个对象的finalize()只会调用一次,下一次System.gc()不会执行 ——不要这么使用!
- JDK 1.2+ 引用类型:
- 强引用
- 软引用(GC检测将内存溢出之前,将这些对象进行第2次回收)
- 弱引用(只能生存到下一次GC之前?)
- Phantom引用(完全不对其生存时间有影响,唯一目的就是希望在GC时收到一个通知?)
- GC算法
- Mark-Sweep:效率低,易碎片
- Copying:内存代价太高
- 商业VM:一块较大的Eden空间,2块较小的Survivor
- Mark-Compact
- 分代gc
- JDK 1.6u22 垃圾收集器
- 年轻代:
- Serial:会停止所有工作线程
- PartNew(Serial的多线程版本)
- Parallel Scavenge:目标是达到一个可控制的吞吐量
- Tenured代
- Serial Old(MSC)
- Parallel Old
- CMS(如果使用则Parallel Scavenge不能用):获取最短gc停顿时间
- G1
- 年轻代:
- VM性能监控与故障处理
- jps
- jstat
- jmap
- jhat
- jstack
- JConsole
- VisualVM
- BTrace(相当于DTrace的java版本)
- 调优案例分析
- 64位JDK性能较低,改为n个32位JDK的逻辑集群?
- 本地缓存 => 集中式
- Runtime.getRuntime().exec():会复制当前虚拟机环境,系统开销大(晕!做成C/S模式查询不就好了)
- JVM崩溃:异步调用模式导致本地等待的线程和socket连接越来越多,改为消息队列(!)
- Eclipse崩溃:1.6u21升级为Oracle后,laucher不识别,不传递-XX:MaxPermSize,需要手工设置
- -Xverify:none 禁止字节码验证
- -Xmn (晕,Eclipse为什么不能够自动检测机器配置,以最优性能配置参数运行呢?st)
- eclipse.ini:-XX:+DisableExplicitGC
- CPU资源充足:-XX:+UseConcMarkSweepGC -XX:+UseParNewGC --> -XX:CMSInitiatingOccupancyFraction=85
- 64位JDK性能较低,改为n个32位JDK的逻辑集群?
- 虚拟机执行子系统:类文件结构
- p144 常量字符串超过64KB,将会无法编译(CONSTANT_Utf8_info.length是u2类型,只有2个字节宽!)
- 属性表?
- p157 不允许指令条数超过65535的方法
- deprecated及synthetic属性(后者,如<init>和<cinit>方法)
- 虚拟机类加载机制
- 初始化时机:
- new getstatic putstatic invokestatic
- java.lang.Reflect
- 初始化一个类,但其父类还没有初始化
- 虚拟机启动时,用户指定的执行主类
- 类加载器
- 自定义ClassLoader影响instanceof判断
- Bootstrap ClassLoader
- 扩展类ClassLoader(sun.misc.Launcher$ExtClassLoader)
- 应用程序/系统ClassLoader:getSystemClassLoader()
- 类加载的Parents Delegation Model
- 收到类加载请求时,首先把这个请求委派给父类loader去完成,——这保证了系统SDK类的不可替换性!(看起来Ruby语言不是这种思路,哈)
- JDK 1.2 + protected ClassLoader#findClass()
- 在此之前,用户继承ClassLoader的唯一目的是为了重写loadClass()
- 现在用户只需要重载findClass(),意思是“在哪里找到这个parent无法加载的类(第3方的库)”
- 新的问题:基础类callback用户类代码?
- Thread Context ClassLoader,可通过Thread#setContextClassLoader()设置,默认就是应用程序/系统ClassLoader
- 有了这个hack-in,JNDI服务就可以用它来加载特定SPI实现了
- 违反了“Parents Delegation Model”
- 其他的:JDBC JCE JAXB JBI
- 第3次“破坏”:动态加载/热部署
- e.g. OSGi:每一个Bundle里都有自己的ClassLoader,树状结构 --> 网状结构(哦!,我好象有点明白OSGi的实现原理了~~)
- 初始化时机:
- 虚拟机字节码执行引擎
- Stack Frame:
- Slot index 0对应this
- 静态分派(参数的重载,overload)
- 动态分派(方法的覆盖,override)
- Stack Frame:
- 类加载及执行子系统的案例实战
- Tomcat
- /common /server /shared(6.x已经合并了前3者) /WebApp/WEB-INF/* <jsp-output-path>
- CommonClassLoader CatalinaClassLoader SharedClassLoader WebappClassLoader JasperClassLoader
- “学习JEE规范,就去看JBoss源代码;学习ClassLoader,就去看OSGi”?
- 循环依赖?JDK 1.7,JSR-297,-277
- 字节码生成与动态代理
- InvocationHandler
- sun.misc.ProxyGenerator
- Retrotranslator:把JDK 1.5 class转为可在1.4上部署的版本
- 远程执行(在服务器中注入执行一段临时代码)
- 把对System.out的引用替换为自己的定制PrintStream:自定义ClassLoader,super本类,并把defineClass()包装为一个public loadBytes接口
- 从bytes数据加载Class对象后,再通过反射调用main方法
- Tomcat
- 程序编译与代码优化
- JSR-269 注解处理器:可以对AST进行修改?(LISP里的宏?)
- javac语义分析:
- attribute() 标注检查
- flow() 数据及控制流分析
- 语法糖:desugar()
- Gen.normalizeDefs() --> ClassWriter.writeClass()
- 实战:javax.annotation.processing.AbstractProcessor#process():返回false代表本回Round没有修改AST
- <C0> C1 C2
- 热点探测(采样)
- Back Edge计数器:触发OSR编译
- 跟踪本地代码生成:-XX:+PrintCFGToFile 需要Debug版VM
- 编译优化
- 通过数据流分析(!),知道循环变量始终在[0, a.length)范围内,不需要数组边界检查。。。
- 虚方法:如何内联?
- 类型继承关系分析(CHA),Guarded Inlining(slow path)
- 逃逸分析
- 栈上分配
- 同步消除
- 标量替换
- 高效并发
- 主内存与工作内存(堆与栈???)
- 局部变量和方法参数是线程私有的
- Java内存模型:lock unlock read load use assign store write
- volatile
- 可见性:synchronized final
- 线程安全
- Immutable对象
- 互斥同步
- 非阻塞同步:
- Test-and-Set
- Fetch-and-Increment
- Swap
- CAS:IA64/x86中的cmpxchg,sparc-TSO中的casa
- LL/SC:ARM和PPC中的ldrex/strex
- 无同步
- 锁优化
- Adaptive Spinning
- Lock Elimination
- Lock Coarsening:StringBuffer对象上连续的append调用
- Lightweight Locking
- Biased Locking
- 主内存与工作内存(堆与栈???)