Java架构知识(更新中)
2020-05-20 17:33:46 0 举报
AI智能生成
java技术大全220/05/18(更新中)
作者其他创作
大纲/内容
java编程思想
面向对象
继承与多态
初始jvm虚拟机
class与反射
Jvm虚拟机
JVM整体架构
类加载器
运行时数据区
程序计数器
栈帧
局部变量表
操作数栈
动态连接
完成出口
本地方法表
堆
方法区
执行引擎
Jvm参数
版本号
次版本号
静态常量池
常量池大小:如果没有常量池为0 所以常量池下计数从1开始数
常量池组成部分
tag:通过这个u1的数字查询对应的常量类型
index:对应class文件中的#数字
长度不固定的名称
类元数据
类访问标志
access_flags
类索引
用于确定该类的全限定名
父类索引
用于确定父类的全限定名
ps:索引都指向常量池中对应的常量
成员变量
用于保存class中的所有成员变量
访问标志
变量名索引
变量属性
魔数ca fe ba be
方法
表格形式存储
方法访问标志位
方法名索引
方法描述索引
属性
属性用于保存class成员变量或者方法的详细持有信息
每个field或者method中都可以包含一个属性表
把静态class文件加载到内存区域
ClassLoader c =new ClassInit.class.getClassLoader();
BootStrap ClassLoader
Extendsion ClassLoader
扩展类加载器
该类负责加载\\lib\\ext目录下的类库
用来加载java的扩展库
开发这可以直接使用这个类加载器
Application ClassLoader
应用程序类加载器
一般我们编写的java类都是由这个类加载器加载
一般情况下这就是系统默认的类加载器
双亲委派模型
优点:java的类随着它的加载器有了优先级关系
钻石依赖
一个程序依赖了两个不同版本的软件包
java通过不同的类加载器实现加载不同版本的软件包
内存分配机制
所有线程共享的
类型的完整有效名
类的直接父类完整有效名
类型的修饰符
类型的常量池
域信息
方法信息
除了常量外的所有静态变量
线程隔离的数据区
程序计数器可以被看作是当前线程所执行的字节码的位置指示器
虚拟机栈
局部变量表存放了编译期间可知的各种基本数据类型
本地方法栈
本地方法栈是虚拟机用到Native方法时,开辟的栈。
栈区
栈是先进后出的:最先进来的是main函数
栈中存放的局部变量表是
分支主题
内存回收GC
对什么区域进行回收
堆中主要是对象存放的区域
引用计数
可达性分析
引用计数器来判断对象是否已\"死\
1虚拟机栈 2.方法区静态属性引用对象 3.方法区中常量引用的对象 4.本地方法栈(Native)引用对象
最终判定
Finalize()方法是对象脱逃死亡命运的最后一次机会,稍后GC将对F-Queue中的对象进行第二次小规模标记,如果对象要在finalize()中成功拯救自己----只要重新与引用链上的任何的一个对象建立关联即可,譬如把自己赋值给某个类变量或对象的成员变量,那在第二次标记时它将移除出“即将回收”的集合。
引用
强引用
强引用是使用最普遍的引用。如果一个对象具有强引用,那垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。
强引用也就是我们常用的new
软引用
如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存
软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。
它可通过SoftReference类实现。
弱引用
弱引用对象会在下一次GC时被回收,也就是说不管内存富不富裕,当GC时都会回收弱引用。
它可通过WeakReference类实现。
虚引用
虚引用不会改变对象的生存时间,它只是让对象在被GC时能收到一个系统通知。
回收算法
标记-清除算法
效率不高;清除和标记效率都低
复制算法
标记整理算法
标记整理算法过程与标记清除算法一样
分代收集算法
新生代:新生代大多数对象都是\"朝生夕死\
垃圾收集器分类
MinorGC
针对新生代
Serial收集器:
ParNew收集器:
server首选的新生代收集器
老年代无力
ParallelScavenge
-xx+userparallelgc
parallelScavenge关注点:可控的吞吐量
吞吐量计算公式:运行用户代码时间/(运行用户代码时间+垃圾收集时间)
适用场景:后台计算不需要太多交互
MajorGC
针对老年代
SerialOld收集器
ParallelOd收集器
这个收集器从jdk1.6开始提供
coucurrentMarkSweep收集器
适用场景:互联网站或web服务器
CMS收集器是一种以获取最短回收停顿时间为目标的收集器.
CMS收集器是基于标记-清除算法实现的.整个过程分为4个步骤
初始标记
初始标记会进行STW暂停时间
这个过程从垃圾回收的\"根对象\"开始,只扫描到能够和\"根对象\"直接关联的对象,并作标记
这个过程只标记了一次所以执行速度快
并发标记
在初始标记的基础上继续向下溯源标记.
并发预清理
并发处理
减少下一个阶段线程停止的时间
重新标记
重新标记会二次进行STW
并发消理
清理对象
并发执行
并发重置
缺点
需要更多cpu:回收线程默认为(CPU数量+3)/4
FUllGC
fullGC针对老年代
=MajorGC+MinorGC
其他fullGC
G1收集器
G1提供了两种模式
youngGC
扫描跟GCRoots
检测RememberSet 哪些数据要从新生到老年
清理工作
MixedG1
初始标记:主要利用了常规的年轻代垃圾回收暂停
并发标记 GC 在整个堆中查找可访问的(存活的)对象。该阶段与应用程序同时运行,可以被 STW 年轻代垃圾回收中断。
最终标记(Remark,STW)该阶段是 STW 回收,帮助完成标记周期。G1 GC 清空 SATB 缓冲区,跟踪未被访问的存活对象,并执行引用处理。
清除垃圾在这个最后阶段,G1 GC 执行统计和 RSet 净化的 STW 操作。在统计期间,G1 GC 会识别完全空的区域和可供进行混合垃圾回收的区域。清理阶段在将空白区域重置并添加到空闲列表时为部分并发。注意完全空的region不会被加到CSet,都在这个阶段直接回收了。
配套机制
jdk1.7-1.8默认回收器:Parallel Scavenge+Parallel Old
JDK1.9是G1
大对象直接进入老年代
JVM内存区域示意图
SafePoint
抢先式中断
STW=stop the world
主动中断.
缺点:Thread.sleep wait
主动中断
子主题 2
安全区域
安全点的衍生概念
安全点以后的一段区域都是安全的
JVM调优
-Xms
启动时占用内存大小.
-XX:SuivivorRatio
控制eden区大小
eden:S0:S1=SurvivorRatio:1:1
100m*(SurvivorRatio/(SurvivorRatio+1+1))
尽量把GC控制在MinorGC
-Xmn 100m
Xmn区大小为100m
Xmn为eden+Survivor0+Survivor1
Xmn内存分配为 总内存*(Survivor/(Survivor+S0(默认值1)+S1(默认值1))
-XX PretenureSizeThreshold=n
可以令大于这个设置值的对象直接在老年代分配
只能用于ParNewGC和Serial这两款收集器
MaxTenuringThreshold
一个对象经历多少次GC进入老年代
默认值5
对象年龄的动态判断
空间分配担保
检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小
流程图
大于执行minorGC
小于执行FUllGC
保证尽量减少FUllGC频率
-Xss
指设定每个线程的堆栈大小
-Xmx
整个设定程序运行期间最大可占用内存大小
内存分配与回收策略
内存分配策略
Eden区
新生小对象进入Eden区
Survivor0区
Survivor1
总称Xmn
老年代
长期存活的对象进入老年代
动态对象年龄判定
JVM监控
java的bin目录除了java.exe以外还有一些jdk自带的工具
jps
功能:显示正在运行的虚拟机进程
参数
-l:显示虚拟机启动进程时传递给main()的参数
-v显示虚拟机启动时的jvm参数
可以jps -lmv 一起使用
jstat
-class
监视类装载/卸载数量、总空间以及耗费的时间
loaded
加载class的数量
bytes
class字节的大小
unloaded
未加载class的数量
未加载class的字节大小
time
加载时间
jinfo
可以在jvm运行时通过该工具增加打印的日志
jmap
-dump
Memory Analyzer Tool 用于分析MAT
-histo
显示堆中对象的统计信息
permstat
显示永久代内存状态
-heap
显示堆详细信息
jsatck
功能:用于生成虚拟机当前时刻的线程快照
用法[-命令选项]
Jconse
图形化检测工具
1.合理的编写程序
2.充分并合理的使用硬件资源
3.合理地进行jvm调优
非堆内存的释放
堆外内存
文件句柄
限制文件大小
异步方式
socket句柄
限制一台服务器吞吐量
数据连接
堆内存
大对象
避免使用大对象
尽量减少大对象的生存时间(朝生夕死) bigObj obj=new bigObj(); obj=null;
提高大对象进入老年代的门槛
降低FullGC频次
重启服务器
一个定时任务触发FullGC
SLA服务等级协议
尽量使用32位版本
目前64位版本效率没有32高
32位最大可用内存4g
64版本内存有接近100g内存
一线互联网的做法
虚拟机或者docker拆分内存
使用CMS垃圾回收器
GC短暂停:适合对于延时要求较高的网络请求
因此MinorGC用ParNew
虚拟机执行策略
基于采样的热点判定
优点:实现简单
缺点:很难精确一个方法的热度
基于计数器的热点判定
回边计数器:主要统计方法中循环体代码执行次数
编译执行
JIT编译器:及时编译器
完全编译成机器码
解释执行
解析器
方法调用
方法调用不等同于方法执行
该阶段唯一能确定的是任务就是确定调用哪一个方法
非虚方法
静态方法
jvm虚拟机中为invokestatic
私有方法
实例构造器
jvm中为invokespecial
父类方法
虚方法
虚函数调用jvm中为invokevirtual
子主题 3
虚拟机动态分派机制
虚方法表(vtabel)
使用虚方法表索引来代替元数据查找以提高性能
类加载器收到请求
委派给父类加载器
搜索自己能否加载该类
自己加载该类
交给子类加载
多线程与高并发
基础概念
什么是线程
一个进程里面最小的基础概念就是线程
线程生命周期
线程常用方法
.sleep
.yield
.join
.getState
获取线程状态
创建线程的3种方法
继承Thread类创建线程
定义Thread类的子类
重写runn()方法
实现Runnable接口创建线程
定义Runnable接口的实现类
重写run()方法
使用Callable和future创建线程
call方法功能比run要强大
Call方法可以有返回值
call方法可以声明抛出异常
匿名类创建线程
启动线程的五种方式
并发编程
锁
可重入锁
synchronized
上锁关键字
用于线程资源安全
synchronized(this)
实现原理
synchronized一共有三把锁
偏向锁
偏向锁,并不是一把锁
而是在锁类信息上增加一个该线程id,表明这个id已经有人在用了
当有另一个锁进入时,锁会升级成自旋锁
自旋锁
自旋锁是有线程自己去查询的
当有一个以上的线程要使用公共资源时,会启动自旋锁,由线程自己去尝试上锁 如果上锁失败会休眠一段时间重新尝试。
当有大量线程进入自旋锁状态时,每个线程都去自己检查会消耗大量cpu资源 此时会升级成重量级锁
重量级锁
有线程超过10次自旋,或者自旋线程数超过CPU核数的一半
由操作系统来进行分配锁,所有线程挂起,进入等待队列,等待操作系统调度。
Thread
多线程
JAVA5新增线程包
自由主题
Set
HashSet
底层结构是HashMap(无序唯一)
存入的时候把值放在key上
如何来保证元素唯一性
hashCode
判断当前hashcode位置是否有元素
equals
相同hashcode则调用equals方法进行比较是否相等
可以存入null
重写put方法
在原hashmapput上通过比对返回值是否等于null来判断是否重复
即便是已经有重复值了还是会进行一次插入
TreeSet
底层数据结构是红黑树。(唯一,有序)
因为要排序来确定插入元素位置所以插入效率低
取出元素需要循环来取因此效率也低
好处是,map有顺序,可以按照重写后的排序依据来排序
不允许有null值
TreeSet中的元素必须实现Comparable接口并重写compareTo()方法
自然排序 比较器排序
通过重写元素的compareTo方法来进行元素比较
TreeSet内部封装了一个TreeMap
将值存入TreeMap的Key
返回值的oldValue是否等于null,如果等于null则非重复插入
HashLinkedSet
底层是LinkedHashMap
性能比HashSet好,但是插入时性能稍微逊色于HashSet。
同时使用链表维护元素的次序
可以根据插入顺序排序或者访问顺序排序
Queue
算法
红黑树
红黑树简介
一个具有平衡性的二叉树
节点有红色或者黑色两种颜色
红黑树特点
节点是红色或者黑色的
根节点是黑色的
每个叶子节点都是黑色的空节点
每个红色节点两个叶子节点都是黑色的
每一个节点到根的路径上都不能有两个相连的红色节点
从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点
树介绍
根节点
位于结构的最上层的节点
有且只有一个
叶子节点
每一个节点下一层的节点都可以称为叶子节点
红黑树的特性
红黑数与平衡二叉平衡树的区别
Spring
RedisSon
Spring-boot
Zookeeper
架构
单一架构
所有功能都部署在一个jar或war中
存在问题
代码耦合
无法针对不同模块进行优化
无法水平扩展
并发能力差
垂直架构
多个服务器同时处理请求
优点
系统拆分实现了流量分担
可以针对不同模块进行优化
方便水平扩展
系统间相互独立
负载均衡复杂
服务之间相互调用,如果一个宕机需要手动修改
分布式架构
根据服务内容具体拆分成模块
高并发
高可用
高容错
异步通讯
架构复杂
负载均衡
服务
OOP
面向对象编程
AOP
面向切面
SOA
面向服务
特点
单一职责
微服务中每一个服务都对应唯一的业务,做的单一职责
微
拆分粒度很小
每个服务都要对外暴露API,并不关心服务的具体实现
自治
每个服务间相互独立,互不干扰
团队独立
技术独立
前后端分离
数据库分离
部署独立
docker
中央仓库地址
官方仓库(最全)
hub.docker.com
国内仓库
http://hub.daocloud.io/
局域网仓库(最快)
/etc/docker/deamon.json添加配置
{registry- mirrors\": [\"https://registry. docker -cn. com\
重启两个服务
daemon -reload restart docker
CI、CD
指定部署项目
CI
CI介绍
continuous intergration 持续集成
编写代码时,完成一个功能后,立即提交代码到git仓库中,并将项目重新构建并测试
快速发现错误
防止代码偏离分支
Gitlib
gitlib是一个运行git的软件
gitlib用于搭建私人服务器
任务清单
收藏
0 条评论
回复 删除
下一页