第九周. 总结
一、JVM虚拟机
1.1 java启动参数
1.标准参数,所有JVM实现都必须实现,且向后兼容
(1)运行模式 -server ,-client
(2)类加载路径 -cp,-classpath
(3)运行调试 -verbose
(4)系统变量 -D
2.非标准参数,默认JVM实现这些参数,不保证所有jvm实现都是先,且不保证向后兼容
(1)-Xms 初始堆大小
(2)-Xmx 最大堆大小
(3)-Xmn 新生代大小
(4)-Xss 线程堆栈大小
3.非Stable参数,各JVM实现会有所不同,将来可能会随时取消
(1) -XX:-UseConcMarkSweepGC 启用CMS垃圾回收
1.2 JVM性能诊断工具
基本工具:JPS,JSTAT,JMAP,JSTACK
集成工具:JConsole,JVisualVM
1.JPS:查看host上运行的所有java进程的pid(jvmid),一般情况下使用这个工具的目的只是为了找出运行jvm的进程ID,然后可以进一步使用其他的工具来监控和分析JVM
2.JSTAT(JAVA Virtual Machine statistics monitoring tool")是JDK自带的一个清凉及的工具,主要对Java应用程序的资源和性能进行实时的命令行的监控,包括了对Heap size和垃圾回收状况的监控
3.JMAP是一个可以输出所有内存中对象的工具,甚至可以将VM中的heap,以二进制输出成文本
4.Jstack可以查看jvm内的线程堆栈信息
二、JAVA代码优化
2.1 合理并谨慎使用多线程
2.2 静态条件与临界区
挡多个线程访问了相同的资源,如果对资源的访问顺序铭感,就称存在竞态条件。导致竞态条件发生的代码去,成为临界区。
在临界区中使用适当的同步就可以避免竞态条件。
2.3 JAVA线程安全
允许被多个线程安全执行的代码称作线程安全的代码
1.方法局部变量
局部变量存储在线程自己的栈中,也就是局部变量永远不会被多个线程共享。所以基础类型的局部变量是线程安全的。
2.方法局部的对象引用
如果在某个方法中创建的对象不会讨一出该方法,那么他就是线程安全的
3.对象成员变量
对象成员存储在堆上,如果两个线程同时更新一个对象的同一个成员,那么这个代码就不是线程安全的。
2.4 内存泄漏
内存泄漏是开发人员的错误引起。如果程序保留对永远不再使用的对象的引用,这些对象将会占用并好近内存
(1) 长生命周期对象
(2) 竞态容器
(3) 缓存
2.5 合理使用线程池和对象池
1.复用线程或对象资源,避免在程序的生命期中创建和删除大量对象
2.池管理算法(记录那些对象是空闲的,那些对象正在使用)
3.对象内容清楚(ThreadLoacal的清空)
2.6 使用合适的JDK容器类(顺序表,链表,Hash)
1.LinkList和ArrayList的区别和使用场景
(1) ArrayList:动态数组的数据结构 LinkedList基于链表的数据结构
(2) 随机访问get和set,由于LinkedList要移动指针,所以ArrayList要由于Linkelist
(3) 对于add or remove,linkedlist要比ArrayList快
2.HashMap的算法实现及应用场景
to be continue
3.使用concurrent包,ConcurrentHashMap与HashMap的区别
HashMap
(1) jdk1.8后,HashMap是由数组+链表/红黑树实现
(2) 可以存储null键和null值
(3) 初始size为16,扩容时,newsize = oldsize * 2.
(4) 线程不安全:在接近扩容的临界点时,如果有两个或多个线程进行put操作,则都会触发resize和rehash,可能会行程链表换。导致put操作近期哦死循环。
(5) Map中袁术总数超过Entry数组的75%,会出发扩容操作
(6) jdk1.8是先插值再扩容
ConcurrentHashMap
底层采用分段的数组+链表实现,线程安全
(1)通过把整个Map分为N个Segment,可以提供相同的线程安全,但是效率提升N倍,默认提升16倍。(读操作不加锁,由于HashEntry的value变量是 volatile的,也能保证读取到最新的值。)
(2)Hashtable的synchronized是针对整张Hash表的,即每次锁住整张表让线程独占,ConcurrentHashMap允许多个修改操作并发进行,其关键在于使用了锁分离技术
(3)有些方法需要跨段,比如size()和containsValue(),它们可能需要锁定整个表而而不仅仅是某个段,这需要按顺序锁定所有段,操作完毕后,又按顺序释放所有段的锁
(4)扩容:段内扩容(段内元素超过该段对应Entry数组长度的75%触发扩容,不会对整个Map进行扩容),插入前检测需不需要扩容,有效避免无效扩容
2.7 缩短对象生命周期,加速垃圾回收
减少对象主流内存的时间
在使用时创建对象,用完释放
创建对象的步骤(静态代码段 -> 静态成员变量 -> 父类构造函数 -> 子类构造函数 ->)
2.8 使用I/O buffer及NION
延迟写与提前度策略
异步物阻塞IO通信
2.9 优先使用组合代替继承
减少对象耦合
避免太深的继承层次带来的对象创建性能损失。
2.10 合理使用单粒模式
无状态对象
线程安全
2.11 计算机的任何问题都可以通过虚拟层(或中间层)解决
1.面向接口变成
2.七层网络协议
3.JVM
4.编程框架
5.一致性Hash算法的虚拟化实现
评论