前言
在上一期Tomcat优化中,针对JVM相关主要参数作过必定说明,这一期主要介绍进行一些概念及经验。后面分章节去讲述相关工具的基本使用。算法
优化优先级
总体来说,系统优化应先优化架构及代码,来解决具体功能点效率问题。最后经过JVM监控工具来发现一些隐藏较为深刻的问题。tomcat
相关情形
- 内存占用并不断增长, 系统压力大状况下Full GC频繁,系统出现卡顿
- 线程出现大量等待及死锁, CPU使用率太高, 系统响应慢
- 堆(heap)内存不足或类加载致使JVM Crash,系统宕机
出现以上状况,就得使用工具分析JVM来肯定问题
JVM内存模型

JDK1.7及如下安全
JDK1.8下,PermGen替换成Vm MetaSpace
Heap域
方法域
- 全局被全部线程分享
- 存全部类的结构定义包含属性,方法及构造函数等
Thread1.N
- 本地私有栈,一个线程一个栈
- 保持着全部在Heap域的对象引用(4byte长度)
- 存储本地局部变量的存储(基础数据类型),程序运行状态,方法返回值
内存泄漏的分类
- 堆内存泄漏 - 比较常见
- 持久代内存泄漏
- 栈内存泄漏
- 系统资源内存泄漏 -比较常见
线程相关知识
JVM线程状态迁移多线程

线程状态
- 初始化(New):初期建立,启动后则进入可执行状态
- 可执行状态(Runnable): 只要获取CPU时间,则开始执行
- 运行状态(Running): 正在使用CPU执行
-
阻塞状态(Bloked)架构
- 等待阻塞(wait)
- 同步阻塞(synchronized)
- 睡眠阻塞(sleep)
- Join阻塞: 等待join子线程结束后,主线程才能执行,将异步执行的线程合并为同步的线程
- 结束状态: 线程执行完毕或者异常退出
性能监控关注点
- 系统线程总数
- 死锁线程 须要优先解决
-
线程Bloked总数数量并发
线程Bloked多的状况下,考虑对待处理数据进行分片,进行多通道,多线程处理提升系统性能
若是系统处理慢,但CPU占用一直很低,就须要梳理系统处理流程,串行处理该并行处理,并行处理流程提升并发来解决。
线程死锁
当两个或者多个线程尝试获取其余资源的锁,而每一个线程又陷入无限等待其余资源锁的释放(相互等待),除非一个用户的进程被终止。异步
几个死锁场景
- 两个线程相互调用Thread.join(), 致使互相等待同步结束。

慎用线程join操做
- 当两个线程使用嵌套的同步块时,一个线程占用了另外一个线程的必需的锁,互相等待时被阻塞,就有可能出现死锁。 也可能多个线程造成环状锁,好比线程A等待线程B,线程B等待线程C,线程C等待线程A。线程A为了检测死锁,它须要递进地检测全部被B请求的锁。从线程B所请求的锁开始,线程A找到了线程C,发现线程C请求的锁被线程A本身持有着。这是它就知道发生了死锁。


MySql中两个线程同时对两条记录作先读后写操做
避免死锁
找到一个分配资源的序列能让全部进程都顺利完成
采用预分配策略检查分配完成时系统是否处在安全状态
检测死锁
监控线程状态,若是出现死锁获得相关代码位置
利用死锁定理化间资源分配图来分析死锁的存在
参见如下资料:
https://www.coursera.org/lect...
总结
本章主要讲了一些核心知识,主要为了让你们了解系统优化到底优化和解决什么问题,什么是优化的目标。后续章节会讲到tomcat的JMX配置,VisualVM,Tprofile等工具的使用。函数
思考题
JVM线程有哪些状态,这些线程大多处于什么样的状态分布, 咱们能够称系统运行是健康的。高并发