JVM

CMS

Concurrent Mode Failure: 当CMS收集器运行过程中年老代留给用户程序的内存空间不足时就会触发这个错误。jvm参数:-XXCMSInitiatingOccupancyFraction表示CMS启动阀值。比如-XXCMSInitiatingOccupancyFraction=92% 表示当年老代(CMS是年老代垃圾回收算法)的内存已经被占用92%时则立刻开始CMS收集。

CMS特点

4个阶段:

- 初始标记:很快,因为只标记GCRoot直接关联的对象,但需要Stop The World

- 并发标记:GCRoot tracing的过程

-重新标记:修正并发标记过程中用户程序继续运行导致标记发生变动的那部分对象的标记记录。需要Stop The World

-并发清除:很快

CMS有哪些缺点?

1. cpu敏感,因为CMS是跟用户程序并行的,那么就会挤占用户程序的计算资源,CMS的线程数=(cpu颗数+3)/4,当cpu颗数小于4时 分配给CMS的cpu资源占比就很客观。

2. Concurrent Mode Failure问题,浮动垃圾(垃圾收集过程中又出现的垃圾)无法清理,可能诱发新一轮FGC

3. 标记-清除(Mark Sweep)会造成内存碎片,为了避免内存碎片太多导致年老代无法创建大对象的问题,提供了相关参数来在必要情况下进行内存整理,这样会消除内存碎片但会造成停顿。

G1 收集器

特点:

1. 并发+并行:就是能够充分利用现代硬件多核资源

2. 分代收集

3. 空间整合:基于标记-整理 而不是标记-清除

4. 可预测的停顿

理解GC日志

值得记住的一句话:日志中里面的参数跟使用的垃圾回收算法有关,换了算法日志就会不同。

内存分配与回收策略

1. 对象在eden区分配,如果空间不足,触发一次Minor GC

2. 大对象(需要大量连续内存空间的对象,比如大数组)直接进入老年代。-XX:PretenureSizeThreshold 设置直接在老年代分配的阀值。注意:新生代(eden+survivor)采用复制算法垃圾收集

3. 长期存活的对象进入老年代

4. 动态对象年龄判断,前三个都太死板,不够灵活。survivor中如果相同年龄对象总和超过survivor空间的一半,那么高于或等于这个年龄的对象可以直接进入老年代。

并发编程

因为计算速度比存储设备快的多,所以在cpu和内存之间引入高速缓存,因为引入高速缓存所以需要解决缓存一致性问题,于是有了内存模型:在特定的操作协议下,对特定的内存或高速缓存进行读写访问的过程抽象。

java内存模型


8种原子操作构成主内存和工作内存之间的交互协议:




java内存模型的特征

1. 原子性:read、load、assign、use、store、write都是原子的,基本数据类型的访问和读写都是原子的。long和double除外。

2. 可见性:volatile,synchronized和final能够保证可见性,即使用的时候一定是经过主内存同步过了。

3. 有序性

happens before

如果A先行发生于B,那么B开始执行时一定能够看到A的操作结果


判断代码是否是线程安全的,就可以用以上这些原则去逐条分析,如果满足以上至少一条,那么就是线程安全的,否则就不是。

java线程


线程安全

CAS:乐观锁,但有ABA问题

synchronized 性能与ReentrantLock性能相当,后者可以绑定多个Condition


锁优化

你可能感兴趣的:(JVM)