锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

最全最新的的Java核心知识点整理!!! 【推荐】

时间:2023-03-12 14:00:01 aqs继电器ne3931热膨胀变送器mss51p继电器

前言: 想要文档版的朋友可以私信我收到,更清晰 一目了然 ~ Java核心知识点!
博客整理出来的有点乱~

  1. 目录

目录 …1
JVM … 19
2.1. 线程 … 20
2.2. JVM 内存区域 … 21
2.2.1. 程序计数器(线程私有) … 22
2.2.2. 虚拟机栈(私有线程) … 22
2.2.3. 本地方法区(私有线程) … 23
2.2.4. 堆(Heap-线程共享-运行时数据区 … 23
2.2.5. 方法区/永久代(线程共享) … 23
2.3. JVM 运行时内存 … 24
2.3.1.
2.3.1.1. 2.3.1.2.
2.3.1.3.
2.3.1.4.
新生代 … 24 Eden 区 … 24 ServivorFrom… 24
ServivorTo … 24
MinorGC 过程(复制->清空->互换) … 24
1:eden、servicorFrom 复制到 ServicorTo,年龄 1… 25
2:清空 eden、servicorFrom… 25 3:ServicorTo 和 ServicorFrom 互换 … 25
2.3.3.1.
2.4.1.
2.4.1.1. 2.4.1.2.
2.4.2. 2.4.3.
2.4.4. 2.4.5.
2.4.5.1. 2.4.5.2.
2.6.1.
2.6.1.1.
2.6.1.2.
2.7.1. 2.7.2. 2.7.3. 2.7.4. 2.7.5. 2.7.6.
2.7.6.1.
2.3.2. 2.3.3.
老年代 … 25 永久代 … 25 JAVA8 与元数据…25 2.4. 垃圾回收与算法 … 26
如何确定垃圾 … 26 引用计数法… 26 可达性分析… 26
标记清除算法(Mark-Sweep) … 27 复制算法(copying)… 27
标记整理算法(Mark-Compact)… 28 分代收集算法 … 29 新一代和复制算法 … 29 标记复制算法 …29 2.5. JAVA 四中引用类型 … 30
2.5.1. 强引用 … 30
2.5.2. 软引用 … 30
2.5.3. 弱引用 … 30
2.5.4. 虚引用 … 30
2.6. GC 分代收集算法 VS 分区收集算法… 30
分代收集算法 … 30 复制算法在新一代… 30 老年-标记整理算法…30
分区收集算法 … 31 2.7. GC 垃圾收集器 … 31
2.6.2.
Serial 垃圾收集器(单线程、复制算法)… 31 ParNew 垃圾收集器(Serial 多线程) … 31 … 32 … 32 … 33 … 33 初始标记 … 33
Parallel Scavenge 收集器(多线程复制算法,高效)
Serial Old 收集器(单线程标记整理算法) )
Parallel Old 收集器(多线程标记整理算法)
CMS 收集器(多线程标记清除算法)
121623125152125125

2.7.6.2. 2.7.6.3. 2.7.6.4.
2.8.1. 2.8.2. 2.8.3. 2.8.4. 2.8.5. 2.8.1. 2.8.2.
2.8.2.1.
2.8.2.2.
2.8.3. 2.8.4. 2.8.5.
并发标记 … 34 重新标记 … 34 并发清除 … 34
G1 收集器 … 34 2.8. JAVA IO/NIO … 34
2.7.7.
2.9.
2.9.2.
2.9.2.1. 2.9.2.2. 2.9.2.3.
2.9.3. 2.9.4.
2.9.4.1. 2.9.4.2.
3.4.1.
3.4.1.1.
3.4.1.2.
3.4.2.
3.4.2.1. 3.4.2.2. 3.4.2.3. 3.4.2.4.
HashMap(数组 链表 红黑树)… 50 JAVA7 实现 … 50 JAVA8 实现 … 51
ConcurrentHashMap… 51 Segment 段… 51 线程安全(Segment 继承 ReentrantLock 加) … 51 并行(默认) 16) … 52 Java8 实现 (引入红黑树) … 52
阻塞IO模型
… 34 … 35 … 35 … 36 … 36 … 36 … 37 NIO 的缓冲区 …38
NIO 的非阻塞 …38 Channel … 40 Buffer… 40 Selector… 40
非阻塞 IO 模型
多路复用 IO 模型
信号驱动 IO 模型
异步IO模型
JAVA IO 包
JAVA NIO
JVM 类加载机制 … 41
2.9.1.1. 2.9.1.2. 2.9.1.3. 2.9.1.4.
2.9.1.5.
2.9.1.6.
2.9.1.7.
2.9.1.8.
加载 … 41 验证 … 41 准备 … 41 解析 … 41
符号引用 … 42 直接引用 … 42
初始化 … 42 类构造器 … 42 类加载器 … 42 启动式加载器(Bootstrap ClassLoader) … 43 扩展加载器(Extension ClassLoader)…43 应用程序类加载器(Application ClassLoader): …43 双亲委派 … 43 OSGI(动态模型系统) … 44 动态改变结构 … 44 模块化编程和热插拔 … 44
3. JAVA集合…45
3.1. 接口继承关系和实现 … 45
3.2. LIST … 47
3.2.1. ArrayList(数组)… 47
3.2.2. Vector(数组实现,线程同步) … 47
3.2.3. LinkList(链表) … 47
3.3. SET … 48
3.3.1.1. 3.3.1.2.
HashSet(Hash 表) … 48 TreeSet(二叉树) … 49
LinkHashSet(HashSet LinkedHashMap) … 49
3.3.1.3.
3.4. MAP… 50
121623125152125125

3.4.3. HashTable(线程安全) … 53
3.4.4. TreeMap(可排序) … 53
3.4.5. LinkHashMap(记录插入顺序) … 53
4. JAVA 多线程并发…54
4.1.1. 4.1.2.
4.1.2.1. 4.1.2.2. 4.1.2.3. 4.1.2.4.
4.1.3.
4.1.3.1. 4.1.3.2. 4.1.3.3.
4.1.3.4.
4.1.4.
4.1.4.1. 4.1.4.2. 4.1.4.3. 4.1.4.4.
JAVA 并发知识库 … 54 JAVA 线程实现/创建方法 … 54 继承 Thread 类 … 54 实现 Runnable 接口。… 54 ExecutorService、Callable、Future 有返回值线程…55 以线程池为基础… 56 4 种线程池 … 56 … 57 … 57 newScheduledThreadPool … 58 newSingleThreadExecutor … 58
线程生命周期(状态) … 58 新建状态(NEW) … 58 就绪状态(RUNNABLE): … 59 运行状态(RUNNING): … 59 阻塞状态(BLOCKED):…59
newCachedThreadPool
newFixedThreadPool
4.1.4.5.
4.1.5.
4.1.5.1. 4.1.5.2. 4.1.5.3. 4.1.5.4.
4.1.6. 4.1.7. 4.1.8. 4.1.9.
4.1.9.1. 4.1.9.2. 4.1.9.3.
4.1.9.4.
Synchronized 同步锁… 64 … 64 … 64
等待阻塞(o.wait->等待对列):
… 59 … 59 … 59 线程死亡(DEAD)… 59 … 59 … 59 … 59 终止线程 4 种方式 … 60 正常运行结束… 60 使用退出标志退出线程…60 Interrupt 结束线程的方法 … 60 stop 方法终止线程(线程不安全)… 61 sleep 与 wait 区别… 61 start 与 run 区别 … 62 JAVA 后台线程 … 62 JAVA 锁 … 63 乐观锁 … 63 悲观锁 … 63 自旋锁 … 63 自旋锁的优缺点…63 自旋锁时间阈值(1.6 引入适应性自旋锁) … 63 打开自旋锁… 64
同步阻塞(lock->锁池)
其他阻塞(sleep/join)
正常结束. 异常结束.
调用 stop
Synchronized 作用范围 Synchronized 核心组件
Synchronized 实现
… 64 ReentrantLock… 66 … 66 … 66 公平锁… 67 … 67 … 67 … 68 tryLock 和 lock 和 lockInterruptibly 的区别… 68
4.1.9.5.
4.1.9.6.
4.1.9.7.
Semaphore 信号量 … 68 … 68 … 68 … 69 AtomicInteger … 69
Lock 接口的主要方法
非公平锁
ReentrantLock 与 synchronized
ReentrantLock 实现
Condition 类和 Object 类锁法的区别
实现互斥锁(计数器为 1)
代码实现
Semaphore 与 ReentrantLock
11623125152125125

4.1.9.8. 4.1.9.9.
4.1.9.10.
4.1.9.12. 重量级锁(Mutex Lock)…71
4.1.9.13. 轻量级锁 … 71 锁升级… 71
可重入锁(递归锁)… 69 公平锁与非公平锁… 70 … 70 … 70 ReadWriteLock 读写锁 … 70 读锁… 70 写锁… 70 4.1.9.11. 共享锁和独占锁 … 70 独占锁… 70 共享锁… 70
公平锁(Fair)
非公平锁(Nonfair)
4.1.9.14. 4.1.9.15. 4.1.9.16.
偏向锁 … 71 分段锁 … 71 锁优化 … 71
减少锁持有时间
… 72 … 72 锁分离… 72 锁粗化… 72 锁消除… 72 4.1.10. 线程基本方法…72
减小锁粒度
4.1.10.1. 4.1.10.2. 4.1.10.3. 4.1.10.4. 4.1.10.5. 4.1.10.6. 4.1.10.7. 4.1.10.8.
线程等待(wait) … 73 线程睡眠(sleep)… 73 线程让步(yield) … 73 线程中断(interrupt)… 73 Join 等待其他线程终止 … 74 为什么要用 join()方法? … 74 线程唤醒(notify)… 74 其他方法: … 74
4.1.11. 线程上下文切换…75
4.1.11.1. 4.1.11.2. 4.1.11.3. 4.1.11.4. 4.1.11.5. 4.1.11.6. 4.1.11.7.
进程 … 75 上下文 … 75 寄存器 … 75 程序计数器 … 75 PCB-“切换桢”… 75 上下文切换的活动: … 76 引起线程上下文切换的原因 … 76
4.1.12. 同步锁与死锁…76 4.1.12.1. 同步锁 … 76 4.1.12.2. 死锁 … 76
4.1.13. 线程池原理…76
4.1.14.1.
4.1.14.2. 4.1.14.3. 4.1.14.4. 4.1.14.5. 4.1.14.6. 4.1.14.7. 4.1.14.8.
4.1.13.1. 4.1.13.2. 4.1.13.3. 4.1.13.4.
线程复用
… 76 … 76 … 78 … 78 4.1.14. JAVA 阻塞队列原理… 79
线程池的组成
拒绝策略
Java 线程池工作过程
阻塞队列的主要方法
… 80 … 80 … 81
… 81 … 82 … 82 … 82 … 82 … 83 … 83
插入操作:
获取数据操作:
Java 中的阻塞队列
ArrayBlockingQueue(公平、非公平)
LinkedBlockingQueue(两个独立锁提高并发)
PriorityBlockingQueue(compareTo 排序实现优先)
DelayQueue(缓存失效、定时任务 )
SynchronousQueue(不存储数据、可用于传递数据)
LinkedTransferQueue
121623125152125125

4.1.14.9. LinkedBlockingDeque … 83 4.1.15. CyclicBarrier、CountDownLatch、Semaphore 的用法 … 84
4.1.15.1. 4.1.15.2. 4.1.15.3.
… 84 … 84 … 85
CountDownLatch(线程计数器 )
CyclicBarrier(回环栅栏-等待至 barrier 状态再全部同时执行)
Semaphore(信号量-控制同时访问的线程个数)
4.1.16. volatile 关键字的作用(变量可见性、禁止重排序) … 87 变量可见性… 87 禁止重排序… 87
… 87 … 87 4.1.17. 如何在两个线程之间共享数据…88 将数据抽象成一个类,并将数据的操作作为这个类的方法…88 … 89
4.1.18. ThreadLocal 作用( )… 90 … 90 … 91
4.1.19. synchronized 和 ReentrantLock 的区别 … 91
4.1.19.1. … 91
4.1.19.2. … 92 4.1.20. ConcurrentHashMap 并发… 92 4.1.20.1. … 92 4.1.20.2. … 92 … 93 4.1.21. Java 中用到的线程调度 … 93
比 sychronized 更轻量级的同步锁
适用场景
Runnable 对象作为一个类的内部类
减小锁粒度
线程本地存储
ThreadLocalMap(线程的一个属性)
使用场景
两者的共同点:
两者的不同点:
4.1.21.1. 4.1.21.2. 4.1.21.3. 4.1.21.4.
ConcurrentHashMap 分段锁
ConcurrentHashMap 是由 Segment 数组结构和 HashEntry 数组结构组成
抢占式调度:
… 93 … 93 … 94 … 94 4.1.22. 进程调度算法…94
4.1.22.1. 4.1.22.2. 4.1.22.3.
协同式调度:
JVM 的线程调度实现(抢占式调度)
线程让出 cpu 的情况:
优先调度算法
… 94 … 95 … 96 )…96 … 96 … 97 … 98 4.1.24. 什么是AQS(抽象的队列同步器)…98
Exclusive 独占资源-ReentrantLock … 99 Share 共享资源-Semaphore/CountDownLatch … 99 同步器的实现是 ABS 核心(state 资源状态计数) … 100 ReentrantReadWriteLock 实现独占和共享两种方式…100
5. JAVA 基础 … 101
4.1.23. 什么是CAS( 4.1.23.1.
4.1.23.2. 4.1.23.3.
高优先权优先调度算法
基于时间片的轮转调度算法
概念及特性
比较并交换-乐观锁机制-锁自旋
原子包 java.util.concurrent.atomic(锁自旋)
ABA 问题
5.1.1.
5.1.1.1. 5.1.1.2.
JAVA 异常分类及处理… 101
概念 … 101
异常分类 … 101 Error… 101 … 101 … 102 … 102 … 102 … 102
Exception(RuntimeException、CheckedException)
5.1.1.3. 5.1.1.4.
异常的处理方式
遇到问题不进行具体处理,而是继续抛给调用者 (throw,throws)
try catch 捕获异常针对性处理方式
Throw 和 throws 的区别:
121623125152125125

5.1.2.
5.1.2.1. 5.1.2.2. 5.1.2.3.
5.1.2.4.
5.1.2.5. 5.1.2.6.
5.1.2.7.
5.1.3.
5.1.3.1. 5.1.3.2.
5.1.3.3.
5.1.4.
5.1.4.1. 5.1.4.2. 5.1.4.3. 5.1.4.4.
5.1.5.
5.1.5.1.
5.1.5.2. 5.1.5.3. 5.1.5.4.
… 102 … 102 JAVA 反射 … 103 … 103
… 103
… 103 … 103 … 104
… 104 … 104 … 104 … 104
… 104 … 104 … 104
位置不同
功能不同:
动态语言
反射机制概念 (运行状态中知道类所有的属性和方法)
反射的应用场合
编译时类型和运行时类型
的编译时类型无法获取具体方法
Java 反射 API
反射 API 用来生成 JVM 中的类、接口或则对象的信息。
反射使用步骤(获取 Class 对象、调用对象方法)
获取 Class 对象的 3 种方法
调用某个对象的 getClass()方法
调用某个类的 class 属性来获取该类对应的 Class 对象
使用 Class 类中的 forName()静态方法(最安全/性能最好)
创建对象的两种方法
Class 对象的 newInstance()
调用 Constructor 对象的 newInstance()
5.1.6.
5.1.7.
5.1.7.1.
5.1.7.2. 5.1.7.3. 5.1.7.4.
6. SPRING
6.1.1.
6.1.1.1.
… 114 … 114 … 115 … 115
… 105 … 105 … 105 JAVA 注解 … 106 概念 … 106 4 种标准元注解… 106 @Target 修饰的对象范围 … 106 @Retention 定义 被保留的时间长短 … 106 … 106 … 106 注解处理器… 107 JAVA 内部类 … 109 静态内部类… 109 成员内部类… 110 局部内部类(定义在方法中的类) … 110 匿名内部类(要继承一个父类或者实现一个接口、直接使用 new 来生成一个对象的引用) … 111 JAVA 泛型 … 112
@Documented 描述-javadoc
@Inherited 阐述了某个被标注的类型是被继承的
泛型方法() … 112 泛型类 … 112 类型通配符? … 113 类型擦除 … 113
JAVA 序列化(创建可复用的 Java 对象) … 113 … 113 … 113 … 113 Serializable 实现序列化 … 113 … 113 … 113 … 113 … 114 … 114 … 114 JAVA 复制 … 114
保存(持久化)对象及其状态到内存或者磁盘
序列化对象以字节数组保持-静态成员不保存
序列化用户远程对象传输
ObjectOutputStream 和 ObjectInputStream 对对象进行序列化及反序列化
writeObject 和 readObject 自定义序列化策略
序列化 ID
序列化并不保存静态变量
序列化子父类说明
Transient 关键字阻止该变量被序列化到文件中
直接赋值复制
浅复制(复制引用但不复制引用的对象)
深复制(复制对象和其应用对象)
序列化(深 clone 一中实现)
原理
Spring 特点… 116
… 116
轻量级 … 116 121623125152125125

控制反转
面向切面
6.1.1.2. 6.1.1.3. 6.1.1.4. 6.1.1.5.
6.1.2. 6.1.3. 6.1.4. 6.1.5. 6.1.6. 6.1.7.
6.1.7.1. 6.1.7.2. 6.1.7.3.
… 116
… 116 容器 … 116 框架集合 … 116
Spring 核心组件… 117 Spring 常用模块… 117 Spring 主要包… 118 Spring 常用注解… 118 Spring 第三方结合… 119 Spring IOC 原理… 120
概念 … 120 Spring 容器高层视图 … 120 IOC 容器实现… 120
BeanFactory-框架基础设施 … 120
1.1…1.1.1 1.1…1.1.2 1.1…1.1.3
1.1…1.1.4 1.1…1.1.5
1.1…1.1.6 1.1…1.1.7 1.1…1.1.8
BeanDefinitionRegistry 注册表… 121 BeanFactory 顶层接口 … 121 ListableBeanFactory … 121
HierarchicalBeanFactory 父子级联… 121 ConfigurableBeanFactory… 121
AutowireCapableBeanFactory 自动装配 … 122 SingletonBeanRegistry 运行期间注册单例 Bean… 122 依赖日志框框…122 ApplicationContext 面向开发应用 … 122 WebApplication 体系架构 … 123 6.1.7.4. Spring Bean 作用域… 123 singleton:单例模式(多线程下不安全) … 123 prototype:原型模式每次使用时创建 … 124 Request:一次 request 一个实例 … 124 session … 124 global Session…124 6.1.7.5. Spring Bean 生命周期… 124 实例化… 124 IOC依赖注入…124 setBeanName 实现… 124 BeanFactoryAware 实现 … 124 ApplicationContextAware 实现… 125
postProcessBeforeInitialization 接口实现-初始化预处理… 125 init-method … 125
postProcessAfterInitialization … 125 Destroy 过期自动清理阶段 … 125 destroy-method 自配置清理 … 125
6.1.7.6. Spring 依赖注入四种方式 … 126 构造器注入… 126 setter方法注入…127 静态工厂注入… 127 实例工厂… 127
6.1.7.7.
6.1.8.
6.1.8.1. 6.1.8.2. 6.1.8.1.
6.1.8.2.
6.1.9.
6.1.9.1.
5 种不同方式的自动装配… 128 Spring APO 原理 … 129 概念 … 129 AOP 核心概念 … 129 AOP 两种代理方式 … 130 JDK 动态接口代理 … 130 CGLib 动态代理… 131
实现原理 … 131 Spring MVC原理…132 MVC 流程… 132 Http 请求到 DispatcherServlet … 133 HandlerMapping 寻找处理器…133 调用处理器 Controller… 133
121623125152125125

Controller 调用业务逻辑处理后,返回 ModelAndView…133 DispatcherServlet 查询 ModelAndView … 133 ModelAndView 反馈浏览器 HTTP … 133
6.1.9.1. MVC 常用注解 … 133 6.1.10. Spring Boot 原理… 134 1. 创建独立的 Spring 应用程序… 134 2. 嵌入的 Tomcat,无需部署 WAR 文件… 134 3. 简化 Maven 配置 … 134 4. 自动配置 Spring … 134 5. 提供生产就绪型功能,如指标,健康检查和外部配置… 134 6. 绝对没有代码生成和对 XML 没有要求配置 [1] … 134 6.1.11. JPA 原理 … 134
6.1.11.1. 6.1.11.2. 6.1.11.1. 6.1.11.1.
事务 … 134 本地事务 … 134 分布式事务 … 135 两阶段提交 … 136
1 准备阶段… 136
2 提交阶段:… 136 6.1.12. Mybatis 缓存… 137 6.1.12.1. Mybatis 的一级缓存原理(sqlsession 级别)…138 6.1.12.2. 二级缓存原理(mapper 基本)…138 具体使用需要配置: … 139 6.1.13. Tomcat 架构 … 139
7. 微服务 … 140
7.1.1.
7.1.1.1. 7.1.1.2.
7.1.1.3. 7.1.1.4. 7.1.1.5. 7.1.1.6. 7.1.1.7. 7.1.1.8.
7.1.2.
7.1.2.1. 7.1.2.2. 7.1.2.3. 7.1.2.4. 7.1.2.5.
7.1.3.
7.1.3.1.
7.1.3.2.
7.1.4.
7.1.5.
7.1.6.
7.1.6.1.
7.1.7.
服务注册发现 … 140 客户端注册(zookeeper) … 140
第三方注册(独立的服务 Registrar) … 140 客户端发现… 141
服务端发现… 142 Consul … 142 Eureka…142 SmartStack … 142 Etcd … 142
API 网关… 142 请求转发 … 143 响应合并 … 143 协议转换 … 143 数据转换 … 143 安全认证 … 144
配置中心 … 144 zookeeper 配置中心 … 144 配置中心数据分类… 144
事件调度(kafka) … 144
服务跟踪(starter-sleuth)… 144
服务熔断(Hystrix) … 145 Hystrix 断路器机制… 146 API 管理 … 146
8. NETTY 与 RPC … 147
8.1.1. 8.1.2.
Netty 原理 … 147 Netty 高性能 … 147 多路复用通讯方式 … 147 异步通讯 NIO … 148 零拷贝(DIRECT BUFFERS使用堆外直接内存)…149 内存池(基于内存池的缓冲区重用机制) … 149 高效的 Reactor 线程模型 … 149 Reactor 单线程模型 … 149 Reactor 多线程模型 … 150
8.1.2.1. 8.1.2.1. 8.1.2.2. 8.1.2.3. 8.1.2.4.
121623125152125125

网络 … 159
9.1.1. 9.1.2.
9.1.2.1. 9.1.2.2. 9.1.2.3. 9.1.2.4.
9.1.3.
9.1.3.1. 9.1.3.2. 9.1.3.3.
9.1.4.
9.1.4.1.
10.
日志 … 169
10.1.1. Slf4j … 169
10.1.2. Log4j … 169
10.1.3. LogBack… 169
10.1.3.1. Logback 优点 … 169 10.1.4. ELK… 170
主从 Reactor 多线程模型 … 150 8.1.2.5. 无锁设计、线程绑定… 151 8.1.2.6. 高性能的序列化框架… 151
小包封大包,防止网络阻塞 … 152 软中断 Hash 值和 CPU 绑定… 152
8.1.3.
8.1.3.1. 8.1.3.2. 8.1.3.3. 8.1.3.1.
Netty RPC 实现… 152 概念 … 152 关键技术 … 152 核心流程 … 152 消息编解码… 153
息数据结构(接口名称+方法名+参数类型和参数值+超时时间+ requestID)…153
序列化… 154 8.1.3.1. 通讯过程 … 154 核心问题(线程暂停、消息乱序) …154 通讯流程… 154 requestID 生成-AtomicLong … 154 存放回调对象 callback 到全局 ConcurrentHashMap … 154 synchronized 获取回调对象 callback 的锁并自旋 wait … 154 监听消息的线程收到消息,找到 callback 上的锁并唤醒 … 155
8.1.4.
8.1.4.1.
8.1.5.
8.1.5.1.
8.1.6.
RMI 实现方式 … 155 实现步骤 … 155 Protoclol Buffer … 156 特点 … 157 Thrift … 157
网络 7 层架构 … 159 TCP/IP 原理… 160 网络访问层(Network Access Layer)… 160 网络层(Internet Layer) … 160 传输层(Tramsport Layer-TCP/UDP) … 160 应用层(Application Layer)… 160 TCP 三次握手/四次挥手 … 161 数据包说明… 161 三次握手 … 162 四次挥手 … 163 HTTP 原理 … 164 传输流程 … 164 1:地址解析 … 164 2:封装 HTTP 请求数据包 … 165 3:封装成 TCP 包并建立连接 … 165 4:客户机发送请求命… 165 5:服务器响应… 165 6:服务器关闭 TCP 连接 … 165 9.1.4.2. HTTP 状态 … 165 9.1.4.3. HTTPS …166 建立连接获取证书…167 证书验证… 167 数据加密和传输…167
9.1.5.
9.1.5.1. 9.1.5.2. 9.1.5.3.
CDN 原理… 167 分发服务系统… 167 负载均衡系统:… 168 管理系统:… 168
121623125152125125

ZOOKEEPER …171
11.1.1. Zookeeper 概念 … 171 11.1.1. Zookeeper 角色 … 171
12.
13.
12.1.1. 消费者设计…177 12.1.1.1. Consumer Group …178
RABBITMQ …179
13.1.1. 概念…179 13.1.2. RabbitMQ 架构 … 179
11.1.1.1. 11.1.1.2. 11.1.1.3.
11.1.1.1.
ZAB 协议 JAVA 实现(FLE-发现阶段和同步合并为 Recovery Phase(恢复阶段))… 173 11.1.1.2. 投票机制 … 173
11.1.2. Zookeeper 工作原理(原子广播)… 174
11.1.3. Znode 有四种形式的目录节点 … 174
KAFKA… 175
12.1.1. Kafka 概念 … 175
12.1.2. Kafka 数据存储设计 … 175
Leader … 171 Follower…171 Observer… 171
ZAB 协议 … 172 事务编号 Zxid(事务请求计数器+ epoch) … 172 epoch… 172 Zab 协议有两种模式-恢复模式(选主)、广播模式(同步)… 172 ZAB 协议 4 阶段 … 172 Leader election(选举阶段-选出准 Leader) … 172 Discovery(发现阶段-接受提议、生成 epoch、接受 epoch) … 173 Synchronization(同步阶段-同步 follower 副本) … 173 Broadcast(广播阶段-leader 消息广播) … 173
12.1.2.1. 12.1.2.2. 12.1.2.3.
partition 的数据文件(offset,MessageSize,data) … 175 数据文件分段 segment(顺序读写、分段命令、二分查找)… 176 数据文件索引(分段索引、稀疏存储) … 176
12.1.3. 生产者设计…176
12.1.3.1. 12.1.3.2. 12.1.3.3.
负载均衡(partition 会均衡分布到不同 broker 上) … 176 批量发送 … 177 压缩(GZIP 或 Snappy) … 177
13.1.2.1. 13.1.2.2. 13.1.2.3. 13.1.2.4. 13.1.2.5. 13.1.2.6. 13.1.2.7. 13.1.2.8. 13.1.2.9. 13.1.2.10.
Message … 180 Publisher … 180 Exchange(将消息路由给队列 ) … 180 Binding(消息队列和交换器之间的关联) … 180 Queue … 180 Connection … 180 Channel … 180 Consumer… 180 Virtual Host …180 Broker … 181
13.1.3. Exchange 类型 … 181
13.1.3.1. 13.1.3.2.
13.1.3.3.
Direct 键(routing key)分布: …181 Fanout(广播分发) … 181
topic 交换器(模式匹配) … 182 121623125152125125

HBASE… 183
14.1.1. 概念…183
14.1.2. 列式存储…183
14.1.3. Hbase 核心概念 … 184
15.
16.
14.1.5. Hbase 的写逻辑 … 187 14.1.5.1. Hbase 的写入流程 … 187 获取 RegionServer … 187 请求写 Hlog … 187 请求写 MemStore … 187 14.1.5.2. MemStore 刷盘 … 187 全局内存控制… 188 MemStore 达到上限… 188 RegionServer 的 Hlog 数量达到上限…188 手工触发… 188 关闭 RegionServer 触发… 188 Region 使用 HLOG 恢复完数据后触发… 188 14.1.6. HBase vs Cassandra…188
MONGODB… 190 15.1.1. 概念…190
15.1.2. 特点…190
CASSANDRA… 192
16.1.1. 概念…192 16.1.2. 数据模型…192 Key Space(对应 SQL 数据库中的 database) … 192 Key(对应 SQL 数据库中的主键)…192 column(对应 SQL 数据库中的列) … 192 super column(SQL 数据库不支持)… 192 Standard Column Family(相对应 SQL 数据库中的 table)… 192 Super Column Family(SQL 数据库不支持) … 192 16.1.3. Cassandra 一致 Hash 和虚拟节点 … 192 一致性 Hash(多米诺 down 机)… 192 虚拟节点(down 机多节点托管) … 193 16.1.4. Gossip 协议 … 193 Gossip 节点的通信方式及收敛性 … 194 Gossip 两个节点(A、B)之间存在三种通信方式(push、pull、push&pull) … 194 gossip 的协议和 seed list(防止集群分列) … 194 16.1.5. 数据复制…194 Partitioners(计算 primary key token 的 hash 函数)… 194 两种可用的复制策略: … 194 SimpleStrategy:仅用于单数据中心, … 194
将第一个 replica 放在由 partitioner 确定的节点中,其余的 replicas 放在上述节点顺时针方向的后续节 点中。… 194
14.1.3.1. 14.1.3.2. 14.1.3.3. 14.1.3.4.
Column Family 列族 … 184 Rowkey(Rowkey 查询,Rowkey 范围扫描,全表扫描)… 184 Region 分区… 184 TimeStamp 多版本… 184
14.1.4. Hbase 核心架构 … 184
14.1.4.1. 14.1.4.2. 14.1.4.3. 14.1.4.4. 14.1.4.5. 14.1.4.6.
Client: … 185 Zookeeper:… 185 Hmaster … 185 HregionServer…185 Region 寻址方式(通过 zookeeper .META) … 186 HDFS … 186
121623125152125125

NetworkTopologyStrategy:可用于较复杂的多数据中心。… 194
可以指定在每个数据中心分别存储多少份 replicas。 … 194
16.1.6. 数据写请求和协调者…195 协调者(coordinator)… 195 16.1.7. 数据读请求和后台修复…195
16.1.8. 数据存储(CommitLog、MemTable、SSTable)…196 SSTable 文件构成(BloomFilter、index、data、static) … 196 16.1.9. 二级索引(对要索引的value摘要,生成RowKey)…196 16.1.10. 数据读写 … 197 数据写入和更新(数据追加) … 197 数据的写和删除效率极高 … 197 错误恢复简单… 197 读的复杂度高… 197 数据删除(column 的墓碑) … 197 墓碑… 198 垃圾回收 compaction … 198 数据读取(memtable+SStables)…198 行缓存和键缓存请求流程图 … 199 Row Cache(SSTables 中频繁被访问的数据)… 199 Bloom Filter(查找数据可能对应的 SSTable)…200 Partition Key Cache(查找数据可能对应的 Partition key) … 200 Partition Summary(内存中存储一些 partition index 的样本) … 200 Partition Index(磁盘中) … 200 Compression offset map(磁盘中)…200
设计模式… 201
17.1.1. 设计原则…201 17.1.2. 工厂方法模式…201 17.1.3. 抽象工厂模式…201 17.1.4. 单例模式…201 17.1.5. 建造者模式…201 17.1.6. 原型模式…201 17.1.7. 适配器模式…201 17.1.8. 装饰器模式…201 17.1.9. 代理模式…201
18.
负载均衡… 203
18.1.1. 四层负载均衡vs七层负载均衡…203 18.1.1.1. 四层负载均衡(目标地址和端口交换) … 203 F5:硬件负载均衡器,功能很好,但是成本很高。 … 203 lvs:重量级的四层负载软件。 … 203 nginx:轻量级的四层负载软件,带缓存功能,正则表达式较灵活。 … 203
17.1.10. 17.1.11. 17.1.12. 17.1.13. 17.1.14. 17.1.15. 17.1.16. 17.1.17. 17.1.18. 17.1.19. 17.1.20. 17.1.21. 17.1.22. 17.1.23. 17.1.24.
外观模式 … 201 桥接模式 … 201 组合模式 … 201 享元模式 … 201 策略模式 … 201 模板方法模式 … 201 观察者模式 … 201 迭代子模式 … 201 责任链模式 … 201 命令模式 … 201 备忘录模式 … 201 状态模式 … 202 访问者模式 … 202 中介者模式 … 202 解释器模式 … 202
121623125152125125

haproxy:模拟四层转发,较灵活。 … 203 18.1.1.2. 七层负载均衡(内容交换) …203 haproxy:天生负载均衡技能,全面支持七层代理,会话保持,标记,路径转移; … 204 nginx:只在 http 协议和 mail 协议上功能比较好,性能与 haproxy 差不多;… 204 apache:功能较差… 204 Mysql proxy:功能尚可。…204 18.1.2. 负载均衡算法/策略…204
18.1.2.1. 18.1.2.2. 18.1.2.3. 18.1.2.4. 18.1.2.5. 18.1.2.6. 18.1.2.7. 18.1.2.8. 18.1.2.9. 18.1.2.10. 18.1.2.11.
轮循均衡(Round Robin) …204 权重轮循均衡(Weighted Round Robin)…204 随机均衡(Random) … 204 权重随机均衡(Weighted Random)…204 响应速度均衡(Response Time 探测时间) … 204 最少连接数均衡(Least Connection)…205 处理能力均衡(CPU、内存) … 205 DNS 响应均衡(Flash DNS) … 205 哈希算法 … 205 IP 地址散列(保证客户端服务器对应关系稳定)…205 URL 散列 … 205
18.1.3. LVS… 206 18.1.3.1. LVS 原理… 206 IPVS …206
18.1.3.1. 18.1.3.2. 18.1.3.3.
18.1.5.1. upstream_module 和健康检测… 212
18.1.5.1. proxy_pass 请求转发 … 212 18.1.6. HAProxy … 213
数据库 …214 19.1.1. 存储引擎…214
LVS NAT 模式 … 207 LVS DR 模式(局域网改写 mac 地址)… 208 LVS TUN 模式(IP 封装、跨网段) … 209
LVS FULLNAT模式…210
18.1.4. Keepalive … 211
18.1.5. Nginx 反向代理负载均衡 … 211
18.1.3.4.
19.1.1.1. 19.1.1.2.
19.1.1.3. 19.1.1.4. 19.1.1.5.
概念 … 214 InnoDB(B+树) … 214
TokuDB(Fractal Tree-节点带数据)…215 MyIASM … 215 Memory… 215
19.1.2. 索引…215 19.1.2.1. 常见索引原则有 … 216 1.选择唯一性索引 … 216 2.为经常需要排序、分组和联合操作的字段建立索引: … 216 3.为常作为查询条件的字段建立索引。 … 216 4.限制索引的数目:… 216 尽量使用数据量少的索引 … 216 尽量使用前缀来索引 … 216 7.删除不再使用或者很少使用的索引 … 216 8 . 最左前缀匹配原则,非常重要的原则。…216 10 . 尽量选择区分度高的列作为索引 … 216 11 .索引列不能参与计算,保持列“干净”:带函数的查询不参与索引。 … 216 12 .尽量的扩展索引,不要新建索引。…216 19.1.3. 数据库三范式…216
第一范式(1st NF -列都是不可再分) … 216
第二范式(2nd NF-每个表只描述一件事情) … 216
第三范式(3rd NF- 不存在对非主键列的传递依赖) … 217 19.1.4. 数据库是事务…217
19.1.3.1.
19.1.3.2.
19.1.3.3.
121623125152125125

原子性(Atomicity)… 217 一致性(Consistency) … 217 隔离性(Isolation) … 218 永久性(Durability) … 218
19.1.5. 存储过程(特定功能的SQL语句集)…218 存储过程优化思路: … 218 19.1.6. 触发器(一段能自动执行的程序)…218 19.1.7. 数据库并发策略…218
19.1.7.1. 19.1.7.2. 19.1.7.3.
乐观锁 … 218 悲观锁 … 219 时间戳 … 219
19.1.8. 数据库锁…219
19.1.8.1. 19.1.8.2. 19.1.8.1.
行级锁 … 219 表级锁 … 219 页级锁 … 219
19.1.9. 基于Redis分布式锁…219 19.1.10. 分区分表 … 220 垂直切分(按照功能模块) …220 水平切分(按照规则划分存储) …220
19.1.11.
19.1.11.1. 19.1.11.2. 19.1.11.3.
两阶段提交协议 … 220 准备阶段 … 221 提交阶段 … 221 缺点 … 221
同步阻塞问题… 221 单点故障… 221 数据不一致(脑裂问题) … 221 二阶段无法解决的问题(数据状态不确定) … 221
19.1.12.
19.1.12.1. 19.1.12.2. 19.1.12.3.
19.1.13.
19.1.13.1.
分区容忍性§:… 224 一致性算法 … 225
20.1.1. Paxos … 225 Paxos 三种角色:Proposer,Acceptor,Learners … 225 Proposer: … 225 Acceptor:…225 Learner:…225 Paxos 算法分为两个阶段。具体如下:… 225 阶段一(准 leader 确定 ): … 225 阶段二(leader 确认): … 225 20.1.2. Zab … 225 1.崩溃恢复:主要就是 Leader 选举过程… 226 2.数据同步:Leader 服务器与其他服务器进行数据同步 … 226 3.消息广播:Leader 服务器将数据发送给其他服务器 … 226 20.1.3. Raft … 226 20.1.3.1. 角色 … 226 Leader(领导者-日志管理) … 226 Follower(追随者-日志同步)… 226 Candidate(候选者-负责选票)… 226
三阶段提交协议 … 222 CanCommit 阶段 … 222 PreCommit 阶段 … 222 doCommit 阶段 … 222
柔性事务 … 222 柔性事务 … 222 两阶段型… 222 补偿型… 222 异步确保型… 223 最大努力通知型(多次尝试) … 223 19.1.14. CAP … 224 一致性©: … 224 可用性(A): … 224
121623125152125125

20.1.3.2. Term(任期) … 226 20.1.3.3. 选举(Election) … 227 选举定时器… 227 20.1.3.4. 安全性(Safety) … 227 20.1.3.5. raft 协议和 zab 协议区别 … 227 20.1.4. NWR… 228 N:在分布式存储系统中,有多少份备份数据… 228 W:代表一次成功的更新操作要求至少有 w 份数据写入成功 … 228 R: 代表一次成功的读数据操作要求至少有 R 份数据成功读取 … 228 20.1.5. Gossip … 228 20.1.6. 一致性Hash…229 20.1.6.1. 一致性 Hash 特性 … 229 20.1.6.2. 一致性 Hash 原理 … 229 1.建构环形 hash 空间:…229 2.把需要缓存的内容(对象)映射到 hash 空间… 229 3.把服务器(节点)映射到 hash 空间 … 229 4.把对象映射到服务节点… 229 考察 cache 的变动 … 230 虚拟节点… 230
JAVA 算法 … 232
21.1.1. 二分查找…232 21.1.2. 冒泡排序算法…232 21.1.3. 插入排序算法…233 21.1.4. 快速排序算法…234 21.1.1. 希尔排序算法…236 21.1.2. 归并排序算法…237 21.1.3. 桶排序算法…240 21.1.4. 基数排序算法…241 21.1.5. 剪枝算法…243 21.1.6. 回溯算法…243 21.1.7. 最短路径算法…243 21.1.8. 最大子数组算法…243 21.1.9. 最长公共子序算法…243 21.1.10. 最小生成树算法 … 243
数据结构… 245
22.1.1. 栈(stack)…245
22.1.2. 队列(queue)…245
22.1.3. 链表(Link)…245
22.1.4. 散列表(Hash Table)…246
22.1.5. 排序二叉树…246
22.
23.
22.1.7. B-TREE… 252 22.1.8. 位图…254
加密算法… 255
23.1.1. AES … 255
23.1.2. RSA … 255
23.1.3. CRC… 256
23.1.4. MD5 … 256
22.1.5.1. 22.1.5.2. 22.1.5.3.
插入操作 … 246 删除操作 … 247 查询操作 … 248
22.1.6. 红黑树…248
22.1.6.1. 22.1.6.1. 22.1.6.1. 22.1.6.1. 22.1.6.2.
红黑树的特性 … 248 左旋 … 248 右旋 … 249 添加 … 250 删除 … 251
121623125152125125

分布式缓存 … 257
24.1.1. 缓存雪崩…257 24.1.2. 缓存穿透…257 24.1.3. 缓存预热…257 24.1.4. 缓存更新…257 24.1.5. 缓存降级…257
HADOOP …259
25.1.1. 概念…259 25.1.2. HDFS … 259
25.
26.
25.1.4. Hadoop MapReduce 作业的生命周期 … 262 1.作业提交与初始化… 262 2.任务调度与监控。… 262 3.任务运行环境准备… 262 4.任务执行 … 262 5.作业完成。 … 262
SPARK… 263
26.1.1. 概念…263 26.1.2. 核心架构…263 Spark Core …263 Spark SQL … 263 Spark Streaming…263 Mllib …263 GraphX … 263 26.1.3. 核心组件…264
Cluster Manager-制整个集群,监控 worker …264
Worker 节点-负责控制计算节点 … 264 Driver: 运行 Application 的 main()函数… 264 Executor:执行器,是为某个 Application 运行在 worker node 上的一个进程 … 264
26.1.4. SPARK 编程模型 … 264
26.1.5. SPARK 计算模型 … 265
26.1.6. SPARK 运行流程 … 266

  1. 构建 Spark Application 的运行环境,启动 SparkContext…267
  2. SparkContext 向资源管理器(可以是 Standalone,Mesos,Yarn)申请运行 Executor 资源,并启
    动 StandaloneExecutorbackend, … 267
  3. Executor 向 SparkContext 申请 Task … 267
  4. SparkContext 将应用程序分发给 Executor… 267
  5. SparkContext 构建成 DAG 图,将 DAG 图分解成 Stage、将 Taskset 发送给 Task Scheduler,最
    后由 Task Scheduler 将 Task 发送给 Executor 运行… 267 6. Task 在 Executor 上运行,运行完释放所有资源… 267
    26.1.7. SPARK RDD 流程 … 267
    26.1.8. SPARK RDD … 267
    (1)RDD 的创建方式… 267
    (2)RDD 的两种操作算子(转换(Transformation)与行动(Action)) … 268 STORM …269

25.1.2.1. 25.1.2.2.
25.1.2.3.
25.1.3.1. 25.1.3.2. 25.1.3.3. 25.1.3.4. 25.1.3.5.
Client…259 NameNode … 259
Secondary NameNode … 259
DataNode… 259 25.1.3. MapReduce … 260
25.1.2.4.
Client … 260 JobTracker … 260 TaskTracker… 261 Task … 261 Reduce Task 执行过程 … 261
121623125152125125

YARN
28.1.1. 28.1.2. 28.1.3.
28.1.4.
28.1.5.
… 275
概念…275 ResourceManager … 275 NodeManager … 275
ApplicationMaster … 276 YARN 运行流程 … 277
30.
机器学习… 278
29.1.1. 决策树…278
29.1.2. 随机森林算法…278
29.1.3. 逻辑回归…278
29.1.4. SVM… 278
29.1.5. 朴素贝叶斯…278
29.1.6. K 最近邻算法… 278
29.1.7. K 均值算法… 278
29.1.8. Adaboost 算法 … 278
29.1.9. 神经网络…278
29.1.10. 马尔可夫 … 278
云计算 …279
30.1.1. SaaS … 279
30.1.2. PaaS … 279
30.1.3. IaaS … 279
30.1.4. Docker… 279
27.1.1. 概念…269 27.1.1. 集群架构…269
27.1.1.1. 27.1.1.2.
27.1.1.3. 27.1.1.4. 27.1.1.5.
Nimbus(master-代码分发给 Supervisor) … 269 Supervisor(slave-管理 Worker 进程的启动和终止) … 269
Worker(具体处理组件逻辑的进程)…269 Task … 270 ZooKeeper … 270
27.1.2. 编程模型(spout->tuple->bolt)…270
27.1.2.1. 27.1.2.2. 27.1.2.3. 27.1.2.4. 27.1.2.5.
Topology… 270 Spout… 270 Bolt … 270 Tuple … 270 Stream … 271
27.1.3. Topology 运行 … 271 (1). Worker(进程) (2). Executor(线程) (3). Task…271
27.1.3.1. 27.1.3.2. 27.1.3.3.
Worker(1 个 worker 进程执行的是 1 个 topology 的子集) … 271 Executor(executor 是 1 个被 worker 进程启动的单独线程)… 271 Task(最终运行 spout 或 bolt 中代码的单元) … 272
27.1.4. Storm Streaming Grouping … 272
27.1.4.1. 27.1.4.2. 27.1.4.3. 27.1.4.4. 27.1.4.5. 27.1.4.6.
huffle Grouping … 273 Fields Grouping … 273 All grouping :广播 … 273 Global grouping … 274 None grouping :不分组 … 274 Direct grouping :直接分组 指定分组 … 274
30.1.4.1. 30.1.4.2.
30.1.4.3. 30.1.4.4.
30.1.4.5. 30.1.4.6. 30.1.4.7.
概念 … 279 Namespaces … 280
进程(CLONE_NEWPID 实现的进程隔离)… 281 Libnetwork 与网络隔离 … 281
资源隔离与 CGroups … 282 镜像与 UnionFS… 282 存储驱动 … 282
121623125152125125

30.1.5. Openstack … 283
121623125152125125

  1. JVM
    (1) 基本概念:
    JVM 是可运行 Java 代码的假想计算机 ,包括一套字节码指令集、一组寄存器、一个栈、 一个垃圾回收,堆 和 一个存储方法域。JVM 是运行在操作系统之上的,它与硬件没有直接 的交互。
    (2) 运行过程:
    121623125152125125

我们都知道 Java 源文件,通过编译器,能够生产相应的.Class 文件,也就是字节码文件, 而字节码文件又通过 Java 虚拟机中的解释器,编译成特定机器上的机器码 。
也就是如下:
1 Java 源文件—->编译器—->字节码文件 2 字节码文件—->JVM—->机器码
每一种平台的解释器是不同的,但是实现的虚拟机是相同的,这也就是 Java 为什么能够 跨平台的原因了 ,当一个程序从开始运行,这时虚拟机就开始实例化了,多个程序启动就会 存在多个虚拟机实例。程序退出或者关闭,则虚拟机实例消亡,多个虚拟机实例之间数据不 能共享。
2.1. 线程
这里所说的线程指程序执行过程中的一个线程实体。JVM 允许一个应用并发执行多个线程。
Hotspot JVM 中的 Java 线程与原生操作系统线程有直接的映射关系。当线程本地存储、缓 冲区分配、同步对象、栈、程序计数器等准备好以后,就会创建一个操作系统原生线程。 Java 线程结束,原生线程随之被回收。操作系统负责调度所有线程,并把它们分配到任何可 用的 CPU 上。当原生线程初始化完毕,就会调用 Java 线程的 run() 方法。当线程结束时,
121623125152125125

会释放原生线程和 Java 线程的所有资源。
Hotspot JVM 后台运行的系统线程主要有下面几个:
虚拟机线程 (VM thread)
这个线程等待 JVM 到达安全点操作出现。这些操作必须要在独立的线程里执行,因为当 堆修改无法进行时,线程都需要 JVM 位于安全点。这些操作的类型有:stop-the-
world 垃圾回收、线程栈 dump、线程暂停、线程偏向锁(biased locking)解除。
周期性任务线程 GC 线程 编译器线程 信号分发线程
这线程负责定时器事件(也就是中断),用来调度周期性操作的执行。 这些线程支持 JVM 中不同的垃圾回收活动。 这些线程在运行时将字节码动态编译成本地平台相关的机器码。 这个线程接收发送到 JVM 的信号并调用适当的 JVM 方法处理。
2.2. JVM 内存区域
JVM 内存区域主要分为线程私有区域【程序计数器、虚拟机栈、本地方法区】、线程共享区 域【JAVA 堆、方法区】、直接内存。
线程私有数据区域生命周期与线程相同, 依赖用户线程的启动/结束 而 创建/销毁(在 Hotspot VM 内, 每个线程都与操作系统的本地线程直接映射, 因此这部分内存区域的存/否跟随本地线程的 生/死对应)。
121623125152125125

线程共享区域随虚拟机的启动/关闭而创建/销毁。
直接内存并不是 JVM 运行时数据区的一部分, 但也会被频繁的使用: 在 JDK 1.4 引入的 NIO 提 供了基于 Channel 与 Buffer 的 IO 方式, 它可以使用 Native 函数库直接分配堆外内存, 然后使用 DirectByteBuffer 对象作为这块内存的引用进行操作(详见: Java I/O 扩展), 这样就避免了在 Java 堆和 Native 堆中来回复制数据, 因此在一些场景中可以显著提高性能。
2.2.1. 程序计数器(线程私有)
一块较小的内存空间, 是当前线程所执行的字节码的行号指示器,每条线程都要有一个独立的
程序计数器,这类内存也称为“线程私有”的内存。
正在执行 java 方法的话,计数器记录的是虚拟机字节码指令的地址(当前指令的地址)。如 果还是 Native 方法,则为空。
这个内存区域是唯一一个在虚拟机中没有规定任何 OutOfMemoryError 情况的区域。
2.2.2. 虚拟机栈(线程私有)
是描述 java 方法执行的内存模型,每个方法在执行的同时都会创建一个栈帧(Stack Frame) 用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至执行完成 的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。
栈帧( Frame)是用来存储数据和部分过程结果的数据结构,同时也被用来处理动态链接 (Dynamic Linking)、 方法返回值和异常分派( Dispatch Exception)。栈帧随着方法调用而创
121623125152125125

建,随着方法结束而销毁——无论方法是正常完成还是异常完成(抛出了在方法内未被捕获的异 常)都算作方法结束。
2.2.3. 本地方法区(线程私有)
本地方法区和 Java Stack 作用类似, 区别是虚拟机栈为执行 Java 方法服务, 而本地方法栈则为 Native 方法服务, 如果一个 VM 实现使用 C-linkage 模型来支持 Native 调用, 那么该栈将会是一个 C 栈,但 HotSpot VM 直接就把本地方法栈和虚拟机栈合二为一。
2.2.4. 堆(Heap-线程共享)-运行时数据区
是被线程共享的一块内存区域,创建的对象和数组都保存在 Java 堆内存中,也是垃圾收集器进行 垃圾收集的最重要的内存区域。由于现代 VM 采用分代收集算法, 因此 Java 堆从 GC 的角度还可以 细分为: 新生代(Eden 区、From Survivor 区和 To Survivor 区)和老年代。
2.2.5. 方法区/永久代(线程共享)
即我们常说的永久代(Permanent Generation), 用于存储被 JVM 加载的类信息、常量、静 态变量、即时编译器编译后的代码等数据. HotSpot VM 把 GC 分代收集扩展至方法区, 即使用 Java 堆的永久代来实现方法区, 这样 HotSpot 的垃圾收集器就可以像管理 Java 堆一样管理这部分内存, 而不必为方法区开发专门的内存管理器(永久带的内存回收的主要目标是针对常量池的回收和类型 的卸载, 因此收益一般很小)。
运行时常量池(Runtime Constant Pool)是方法区的一部分。Class 文件中除了有类的版 本、字段、方法、接口等描述等信息外,还有一项信息是常量池
121623125152125125

(Constant Pool Table),用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加 载后存放到方法区的运行时常量池中。 Java 虚拟机对 Class 文件的每一部分(自然也包括常量 池)的格式都有严格的规定,每一个字节用于存储哪种数据都必须符合规范上的要求,这样才会 被虚拟机认可、装载和执行。
2.3. JVM 运行时内存
Java 堆从 GC 的角度还可以细分为: 新生代(Eden 区、From Survivor 区和 To Survivor 区)和老年
代。
MinorGC 进行垃圾回收。新生代又分为 Eden 区、ServivorFrom、ServivorTo 三个区。
2.3.1.1. Eden 区
Java 新对象的出生地(如果新创建的对象占用内存很大,则直接分配到老 年代)。当 Eden 区内存不够的时候就会触发 MinorGC,对新生代区进行 一次垃圾回收。
2.3.1.2. ServivorFrom
上一次 GC 的幸存者,作为这一次 GC 的被扫描者。
2.3.1.3. ServivorTo
保留了一次 MinorGC 过程中的幸存者。
2.3.1.4. MinorGC 的过程(复制->清空->互换)
MinorGC 采用复制算法。
2.3.1. 新生代
是用来存放新生的对象。一般占据堆的 1/3 空间。由于频繁创建对象,所以新生代会频繁触发
121623125152125125

1:eden、servicorFrom 复制到 ServicorTo,年龄+1
首先,把 Eden 和 ServivorFrom 区域中存活的对象复制到 ServicorTo 区域(如果有对象的年 龄以及达到了老年的标准,则赋值到老年代区),同时把这些对象的年龄+1(如果 ServicorTo 不 够位置了就放到老年区);
2:清空 eden、servicorFrom
然后,清空 Eden 和 ServicorFrom 中的对象;
3:ServicorTo 和 ServicorFrom 互换
最后,ServicorTo 和 ServicorFrom 互换,原 ServicorTo 成为下一次 GC 时的 ServicorFrom
区。
老年代的对象比较稳定,所以 MajorGC 不会频繁执行。在进行 MajorGC 前一般都先进行 了一次 MinorGC,使得有新生代的对象晋身入老年代,导致空间不够用时才触发。当无法找到足 够大的连续空间分配给新创建的较大对象时也会提前触发一次 MajorGC 进行垃圾回收腾出空间。
MajorGC 采用标记清除算法:首先扫描一次所有老年代,标记出存活的对象,然后回收没 有标记的对象。MajorGC 的耗时比较长,因为要扫描再回收。MajorGC 会产生内存碎片,为了减 少内存损耗,我们一般需要进行合并或者标记出来方便下次直接分配。当老年代也满了装不下的 时候,就会抛出 OOM(Out of Memory)异常。
2.3.3. 永久代
指内存的永久保存区域,主要存放 Class 和 Meta(元数据)的信息,Class 在被加载的时候被 放入永久区域,它和和存放实例的区域不同,GC 不会在主程序运行期对永久区域进行清理。所以这 也导致了永久代的区域会随着加载的 Class 的增多而胀满,最终抛出 OOM 异常。
2.3.3.1. JAVA8 与元数据
在 Java8 中,永久代已经被移除,被一个称为“元数据区”(元空间)的区域所取代。元空间 的本质和永久代类似,元空间与永久代之间最大的区别在于:元空间并不在虚拟机中,而是使用 本地内存。因此,默认情况下,元空间的大小仅受本地内存限制。类的元数据放入 native memory, 字符串池和类的静态变量放入 java 堆中,这样可以加载多少类的元数据就不再由 MaxPermSize 控制, 而由系统的实际可用空间来控制。
2.3.2. 老年代 主要存放应用程序中生命周期长的内存对象。
121623125152125125

2.4. 垃圾回收与算法
2.4.1. 如何确定垃圾 2.4.1.1. 引用计数法
在 Java 中,引用和对象是有关联的。如果要操作对象则必须用引用进行。因此,很显然一个简单 的办法是通过引用计数来判断一个对象是否可以回收。简单说,即一个对象如果没有任何与之关 联的引用,即他们的引用计数都不为 0,则说明对象不太可能再被用到,那么这个对象就是可回收 对象。
2.4.1.2. 可达性分析
为了解决引用计数法的循环引用问题,Java 使用了可达性分析的方法。通过一系列的“GC roots”
对象作为起点搜索。如果在“GC roots”和一个对象之间没有可达路径,则称该对象是不可达的。
121623125152125125

要注意的是,不可达对象不等价于可回收对象,不可达对象变为可回收对象至少要经过两次标记 过程。两次标记后仍然是可回收对象,则将面临回收。
2.4.2. 标记清除算法(Mark-Sweep)
2.4.3. 复制算法(copying)
最基础的垃圾回收算法,分为两个阶段,标注和清除。标记阶段标记出所有需要回收的对象,清 除阶段回收被标记的对象所占用的空间。如图
从图中我们就可以发现,该算法最大的问题是内存碎片化严重,后续可能发生大对象不能找到可 利用空间的问题。
为了解决 Mark-Sweep 算法内存碎片化的缺陷而被提出的算法。按内存容量将内存划分为等大小 的两块。每次只使用其中一块,当这一块内存满后将尚存活的对象复制到另一块上去,把已使用 的内存清掉,如图:
121623125152125125

这种算法虽然实现简单,内存效率高,不易产生碎片,但是最大的问题是可用内存被压缩到了原 本的一半。且存活对象增多的话,Copying 算法的效率会大大降低。
2.4.4. 标记整理算法(Mark-Compact)
结合了以上两个算法,为了避免缺陷而提出。标记阶段和 Mark-Sweep 算法相同,标记后不是清 理对象,而是将存活对象移向内存的一端。然后清除端边界外的对象。如图:
121623125152125125

2.4.5. 分代收集算法
分代收集法是目前大部分 JVM 所采用的方法,其核心思想是根据对象存活的不同生命周期将内存 划分为不同的域,一般情况下将 GC 堆划分为老生代(Tenured/Old Generation)和新生代(Young Generation)。老生代的特点是每次垃圾回收时只有少量对象需要被回收,新生代的特点是每次垃 圾回收时都有大量垃圾需要被回收,因此可以根据不同区域选择不同的算法。
2.4.5.1. 新生代与复制算法
目前大部分 JVM 的 GC 对于新生代都采取 Copying 算法,因为新生代中每次垃圾回收都要 回收大部分对象,即要复制的操作比较少,但通常并不是按照 1:1 来划分新生代。一般将新生代 划分为一块较大的 Eden 空间和两个较小的 Survivor 空间(From Space, To Space),每次使用
Eden 空间和其中的一块 Survivor 空间,当进行回收时,将该两块空间中还存活的对象复制到另 一块 Survivor 空间中。
2.4.5.2. 老年代与标记复制算法
而老年代因为每次只回收少量对象,因而采用 Mark-Compact 算法。

  1. JAVA 虚拟机提到过的处于方法区的永生代(Permanet Generation),它用来存储 class 类,
    常量,方法描述等。对永生代的回收主要包括废弃常量和无用的类。
  2. 对象的内存分配主要在新生代的 Eden Space 和 Survivor Space 的 From Space(Survivor 目
    前存放对象的那一块),少数情况会直接分配到老生代。
  3. 当新生代的 Eden Space 和 From Space 空间不足时就会发生一次 GC,进行 GC 后,Eden Space 和 From Space 区的存活对象会被挪到 To Space,然后将 Eden Space 和 From Space 进行清理。
  4. 如果 To Space 无法足够存储某个对象,则将这个对象存储到老生代。
  5. 在进行 GC 后,使用的便是 Eden Space 和 To Space 了,如此反复循环。
  6. 当对象在 Survivor 区躲过一次 GC 后,其年龄就会+1。默认情况下年龄到达 15 的对象会被 移到老生代中。
    121623125152125125

2.5. JAVA 四中引用类型 2.5.1. 强引用
在 Java 中最常见的就是强引用,把一个对象赋给一个引用变量,这个引用变量就是一个强引 用。当一个对象被强引用变量引用时,它处于可达状态,它是不可能被垃圾回收机制回收的,即 使该对象以后永远都不会被用到 JVM 也不会回收。因此强引用是造成 Java 内存泄漏的主要原因之 一。
2.5.2. 软引用
软引用需要用 SoftReference 类来实现,对于只有软引用的对象来说,当系统内存足够时它
不会被回收,当系统内存空间不足时它会被回收。软引用通常用在对内存敏感的程序中。
2.5.3. 弱引用
弱引用需要用 WeakReference 类来实现,它比软引用的生存期更短,对于只有弱引用的对象
来说,只要垃圾回收机制一运行,不管 JVM 的内存空间是否足够,总会回收该对象占用的内存。
2.5.4. 虚引用
2.6.GC分代收集算法 VS分区收集算法 2.6.1. 分代收集算法
2.6.1.1. 在新生代-复制算法
2.6.1.2. 在老年代-标记整理算法
虚引用需要 PhantomReference 类来实现,它不能单独使用,必须和引用队列联合使用。虚 引用的主要作用是跟踪对象被垃圾回收的状态。
当前主流 VM 垃圾收集都采用”分代收集”(Generational Collection)算法, 这种算法会根据 对象存活周期的不同将内存划分为几块, 如 JVM 中的 新生代、老年代、永久代,这样就可以根据 各年代特点分别采用最适当的 GC 算法
每次垃圾收集都能发现大批对象已死, 只有少量存活. 因此选用复制算法, 只需要付出少量 存活对象的复制成本就可以完成收集.
因为对象存活率高、没有额外空间对它进行分配担保, 就必须采用“标记—清理”或“标 记—整理”算法来进行回收, 不必进行内存复制, 且直接腾出空闲内存.
121623125152125125

2.6.2. 分区收集算法
分区算法则将整个堆空间划分为连续的不同小区间, 每个小区间独立使用, 独立回收. 这样做的
好处是可以控制一次回收多少个小区间
, 根据目标停顿时间, 每次合理地回收若干个小区间(而不是
整个堆), 从而减少一次 GC 所产生的停顿。
2.7. GC 垃圾收集器
Java 算法;
堆内存被划分为新生代和年老代两部分,新生代主要使用复制和标记-清除垃圾回收
年老代主要使用标记-整理垃圾回收算法,因此 java 虚拟中针对新生代和年老代分别提供了多种不
同的垃圾收集器,JDK1.6 中 Sun HotSpot 虚拟机的垃圾收集器如下:
2.7.1. Serial 垃圾收集器(单线程、复制算法)
Serial(英文连续)是最基本垃圾收集器,使用复制算法,曾经是 JDK1.3.1 之前新生代唯一的垃圾 收集器。Serial 是一个单线程的收集器,它不但只会使用一个 CPU 或一条线程去完成垃圾收集工 作,并且在进行垃圾收集的同时,必须暂停其他所有的工作线程,直到垃圾收集结束。
Serial 垃圾收集器虽然在收集垃圾过程中需要暂停所有其他的工作线程,但是它简单高效,对于限 定单个 CPU 环境来说,没有线程交互的开销,可以获得最高的单线程垃圾收集效率,因此 Serial
垃圾收集器依然是 java 虚拟机运行在 Client 模式下默认的新生代垃圾收集器。
2.7.2. ParNew垃圾收集器(Serial+多线程)
ParNew 垃圾收集器其实是 Serial 收集器的多线程版本,也使用复制算法,除了使用多线程进行垃 圾收集之外,其余的行为和 Serial 收集器完全一样,ParNew 垃圾收集器在垃圾收集过程中同样也 要暂停所有其他的工作线程。
121623125152125125

ParNew 收集器默认开启和 CPU 数目相同的线程数,可以通过-XX:ParallelGCThreads 参数来限 制垃圾收集器的线程数。【Parallel:平行的】
ParNew 虽然是除了多线程外和 Serial 收集器几乎完全一样,但是 ParNew 垃圾收集器是很多 java 虚拟机运行在 Server 模式下新生代的默认垃圾收集器。
2.7.3. Parallel Scavenge 收集器(多线程复制算法、高效)
Parallel Scavenge 收集器也是一个新生代垃圾收集器,同样使用复制算法,也是一个多线程的垃 圾收集器,它重点关注的是程序达到一个可控制的吞吐量(Thoughput,CPU 用于运行用户代码 的时间/CPU 总消耗时间,即吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)), 高吞吐量可以最高效率地利用 CPU 时间,尽快地完成程序的运算任务,主要适用于在后台运算而
不需要太多交互的任务。自适应调节策略也是 ParallelScavenge 收集器与 ParNew 收集器的一个 重要区别。
2.7.4. SerialOld收集器(单线程标记整理算法)
Serial Old 是 Serial 垃圾收集器年老代版本,它同样是个单线程的收集器,使用标记-整理算法, 这个收集器也主要是运行在 Client 默认的 java 虚拟机默认的年老代垃圾收集器。
在 Server 模式下,主要有两个用途:

  1. 在 JDK1.5 之前版本中与新生代的 Parallel Scavenge 收集器搭配使用。
  2. 作为年老代中使用 CMS 收集器的后备垃圾收集方案。
    新生代 Serial 与年老代 Serial Old 搭配垃圾收集过程图:
    新生代 Parallel Scavenge 收集器与 ParNew 收集器工作原理类似,都是多线程的收集器,都使 用的是复制算法,在垃圾收集过程中都需要暂停所有的工作线程。新生代 Parallel Scavenge/ParNew 与年老代 Serial Old 搭配垃圾收集过程图:
    121623125152125125

2.7.5. ParallelOld收集器(多线程标记整理算法)
Parallel Old 收集器是 Parallel Scavenge 的年老代版本,使用多线程的标记-整理算法,在 JDK1.6 才开始提供。
在 JDK1.6 之前,新生代使用 ParallelScavenge 收集器只能搭配年老代的 Serial Old 收集器,只 能保证新生代的吞吐量优先,无法保证整体的吞吐量,Parallel Old 正是为了在年老代同样提供吞 吐量优先的垃圾收集器,如果系统对吞吐量要求比较高,可以优先考虑新生代 Parallel Scavenge 和年老代 Parallel Old 收集器的搭配策略。
新生代 Parallel Scavenge 和年老代 Parallel Old 收集器搭配运行过程图:
2.7.6. CMS收集器(多线程标记清除算法)
2.7.6.1. 初始标记
只是标记一下 GC Roots 能直接关联的对象,速度很快,仍然需要暂停所有的工作线程。
Concurrent mark sweep(CMS)收集器是一种年老代垃圾收集器,其最主要目标是获取最短垃圾 回收停顿时间,和其他年老代使用标记-整理算法不同,它使用多线程的标记-清除算法。
最短的垃圾收集停顿时间可以为交互比较高的程序提高用户体验。
CMS 工作机制相比其他的垃圾收集器来说更复杂,整个过程分为以下 4 个阶段:
121623125152125125

2.7.6.2. 并发标记
进行 GC Roots 跟踪的过程,和用户线程一起工作,不需要暂停工作线程。
2.7.6.3. 重新标记
2.7.6.4. 并发清除
为了修正在并发标记期间,因用户程序继续运行而导致标记产生变动的那一部分对象的标记 记录,仍然需要暂停所有的工作线程。
清除 GC Roots 不可达对象,和用户线程一起工作,不需要暂停工作线程。由于耗时最长的并 发标记和并发清除过程中,垃圾收集线程可以和用户现在一起并发工作,所以总体上来看 CMS 收集器的内存回收和用户线程是一起并发地执行。
CMS 收集器工作过程:
2.7.7. G1收集器
Garbage first 垃圾收集器是目前垃圾收集器理论发展的最前沿成果,相比与 CMS 收集器,G1 收 集器两个最突出的改进是:

  1. 基于标记-整理算法,不产生内存碎片。
  2. 可以非常精确控制停顿时间,在不牺牲吞吐量前提下,实现低停顿垃圾回收。
    G1 收集器避免全区域垃圾收集,它把堆内存划分为大小固定的几个独立区域,并且跟踪这些区域 的垃圾收集进度,同时在后台维护一个优先级列表,每次根据所允许的收集时间,优先回收垃圾 最多的区域。区域划分和优先级区域回收机制,确保 G1 收集器可以在有限时间获得最高的垃圾收 集效率。
    2.8. JAVA IO/NIO 2.8.1. 阻塞 IO 模型
    最传统的一种 IO 模型,即在读写数据过程中会发生阻塞现象。当用户线程发出 IO 请求之后,内 核会去查看数据是否就绪,如果没有就绪就会等待数据就绪,而用户线程就会处于阻塞状态,用 户线程交出 CPU。当数据就绪之后,内核会将数据拷贝到用户线程,并返回结果给用户线程,用
    121623125152125125

户线程才解除 block 状态。典型的阻塞 IO 模型的例子为:data = socket.read();如果数据没有就 绪,就会一直阻塞在 read 方法。
2.8.2. 非阻塞 IO 模型
当用户线程发起一个 read 操作后,并不需要等待,而是马上就得到了一个结果。如果结果是一个 error 时,它就知道数据还没有准备好,于是它可以再次发送 read 操作。一旦内核中的数据准备 好了,并且又再次收到了用户线程的请求,那么它马上就将数据拷贝到了用户线程,然后返回。 所以事实上,在非阻塞 IO 模型中,用户线程需要不断地询问内核数据是否就绪,也就说非阻塞 IO 不会交出 CPU,而会一直占用 CPU。典型的非阻塞 IO 模型一般如下:
while(true){
data = socket.read(); if(data!= error){ 处理数据
break;
}
}
但是对于非阻塞 IO 就有一个非常严重的问题,在 while 循环中需要不断地去询问内核数据是否就 绪,这样会导致 CPU 占用率非常高,因此一般情况下很少使用 while 循环这种方式来读取数据。
2.8.3. 多路复用 IO 模型
多路复用 IO 模型是目前使用得比较多的模型。Java NIO 实际上就是多路复用 IO。在多路复用 IO 模型中,会有一个线程不断去轮询多个 socket 的状态,只有当 socket 真正有读写事件时,才真 正调用实际的 IO 读写操作。因为在多路复用 IO 模型中,只需要使用一个线程就可以管理多个 socket,系统不需要建立新的进程或者线程,也不必维护这些线程和进程,并且只有在真正有 socket 读写事件进行时,才会使用 IO 资源,所以它大大减少了资源占用。在 Java NIO 中,是通 过 selector.select()去查询每个通道是否有到达事件,如果没有事件,则一直阻塞在那里,因此这 种方式会导致用户线程的阻

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章