JVM调优(一)底层原理分析和问题定位
在这里,假设你已经读过《深入理解Java虚拟机》或者类似的书籍或查看过官方文档。
这个话题从为什么开始。
在虚拟机执行时,有时候会遇到各种线上问题。比如CPU使用居高不下,内存消耗过多,IO读写频繁等问题。我们得找到相应的方法来确定问题所在,再想出对策。
CPU占用问题
CPU占用高原因分析
原因a: 线程上下文切换消耗。
每个cpu或多核cpu中的一核,同一时间只能执行一个线程。在Java应用中,进行文件IO操作、网络IO操作、锁等待或者线程Sleep时,当前线程会进入阻塞或休眠状态,从而触发线程上下文切换,上下文切换过于频繁会造成内核占用过多的cpu资源,导致应用的响应变慢。
原因b:cpu上的运行队列。
每个核上处理runnable的线程的线程线反应其负载(load),load越大,核用越长的时间来完成。(建议每个核上load为1-3个)
原因c:cpu的利用率。
cpu利用率:用户进程、内核、中断处理、IO等待以及空闲五个部分组成。用户进程占用65-70%为宜,而内核占用为30-35%左右。
查看cpu使用情况工具
可用top或pidstat来查看cpu的使用情况。
top
使用top命令后,第三行为我们比较关注的信息。us(用户占用)、sy(系统占用)、ni(改变优先级占用)、id(空闲)。
对于多核cpu,可以按1显示每核的消耗情况。
以上默认为进程信息,如果要看线程信息,可以按shift+h来显示。
pidstat
此工具可以查看线程占用cpu情况,输入pidstat 1 2,表示在控制台上一秒输出一次,一共输出2次。可以多次查看。
分析cpu占用高的各种情况
us:用户占用高
top之后,发现us的百分比过高,表明应用消耗大部分cpu。我们得找到线程id,转换成16进制(linux上),再采用kill -3 [javapid]或jstack [javapid]来查看或dump导出查看。
当然,这部分占用高可能的原因是:线程一直处于runnable状态,通常是无阻塞、循环、正则或纯粹计算动作。
另一个可能是频繁的GC,最主要是Full GC。要从JVM内存消耗上查找原因。
sy:内核占用高
top之后,sy占用高,说明linux花费太多时间用于切换线程,造成这种情况主要原因是java应用启动的线程过多,且这些应用不断处于阻塞和执行状态变化之中,导致了操作系统要不断的进行线程上下文切换。按照上面的方法导出线程信息,查看线程状态、锁信息,找出等待状态或锁竞争过多的线程。
- 文件IO消耗
原因分析
在linux上,物理空闲内存够用,通常只有写文件时或者第一次读取文件时才会产生真正IO。
文件IO消耗的跟踪工具
pidstat
输入 pidstat -d -t - p [pid] 1 100,查看指定进程的io和额外信息。找到其中的io消耗高的线程,之后结合jstack来进一步分析,找到对应的java代码。
- 网线IO消耗
暂时略
- 内存消耗
内存消耗原因分析
多数生产情况下,通常将-Xms和-Xmx设为相同的值,避免运行期频繁申请内存。目前只有创建线程和使用Direct ByteBuffer时才会操作jvm堆外的内存。JVM内存消耗过多会导致GC执行频繁,CPU消耗增加。应用执行速度严重下降,严重会造成OutOfMemeryError,导致java进程退出。所以出现内存消耗过大问题时,根据以下详细分析,找出是jvm外的物理内存占用还是JVM Heap区。
如果os物理内存消耗过大,可能是JVM内存设置过大、创建的线程过多或Direct ByteBuffer往物理内存里放置过多的对象造成。
堆内存设置比物理内存大更容易出现问题。
Direct ByteBuffer是直接使用物理内存的,但是GC负责回收释放。
创建的线程数也会影响物理内存,这取决于-Xss值的大小,也取决于栈的深度。
内存查看工具
top
此工具查看的进行占用情况不太准,查看的为进程的占用全部内存。因为jvm启用时,会按照堆内存设置提前占据内存空间,但不表明在jvm里此内存已经被使用。
pidstat
pidstat -r -p [pid] [interval] [times],可查看指定进程的内存占用信息(包括物理内存和虚拟内存)。
程序执行慢的原因
锁竞争激烈
比较典型的是数据库连接池是有限的,而程序开太多的线程,那么有很多线程处于阻塞等待状态。
硬件资源未充分
这个好理解,多核CPU,只用单线程运行的话,无法充分发挥硬件优势。
数据量增长
这主要是相对数据库来说,若从1万条上升到1亿条,那么在查询时,应用程序多处在等待数据库给结果阶段。
那么知道以上原因和分析工具后,我们可以对jvm进行调优操作。
工具的常用命令:
jstack:
jstack [ option ] pid
jstack [ option ] executable core
jstack [ option ] [server-id@]remote-hostname-or-IP
1)、options:
executable Java executable from which the core dump was produced.
(可能是产生core dump的java可执行程序)
core 将被打印信息的core dump文件
remote-hostname-or-IP 远程debug服务的主机名或ip
server-id 唯一id,假如一台主机上多个远程debug服务
2)、基本参数:
-F当’jstack [-l] pid’没有相应的时候强制打印栈信息
-l长列表. 打印关于锁的附加信息,例如属于java.util.concurrent的ownable synchronizers列表.
-m打印java和native c/c++框架的所有栈信息.
-h | -help打印帮助信息
pid 需要被打印配置信息的java进程id,可以用jps查询.
pidstat
pidstat [ 选项 ] [ <时间间隔> ] [ <次数> ]
常用的参数:
-u:默认的参数,显示各个进程的cpu使用统计
-r:显示各个进程的内存使用统计
-d:显示各个进程的IO使用情况
-p:指定进程号
-w:显示每个进程的上下文切换情况
-t:显示选择任务的线程的统计信息外的额外信息
-T { TASK | CHILD | ALL }
这个选项指定了pidstat监控的。TASK表示报告独立的task,CHILD关键字表示报告进程下所有线程统计信息。ALL表示报告独立的task和task下面的所有线程。
注意:task和子线程的全局的统计信息和pidstat选项无关。这些统计信息不会对应到当前的统计间隔,这些统计信息只有在子线程kill或者完成的时候才会被收集。
-V:版本号
-h:在一行上显示了所有活动,这样其他程序可以容易解析。
-I:在SMP环境,表示任务的CPU使用率/内核数量
-l:显示命令名和所有参数
JVM调优(一)底层原理分析和问题定位相关推荐
- java虚拟机线程调优与底层原理分析_Java并发编程——多线程的底层原理
" Java代码在编译后会变成Java字节码,字节码被类加载器加载到JVM里,JVM执行字节码,最终需要转化为汇编指令在CPU上执行,Java中所使用的并发机制依赖于JVM的实现和 CPU的 ...
- java虚拟机线程调优与底层原理分析_啃碎并发(七):深入分析Synchronized原理...
原标题:啃碎并发(七):深入分析Synchronized原理 前言 记得开始学习Java的时候,一遇到多线程情况就使用synchronized,相对于当时的我们来说synchronized是这么的神奇 ...
- JVM 调优实战--使用jstack分析线程执行情况
目录 jstack的使用 线程的6种状态 使用jstack分析死锁示例 jstack的使用 jstack命令可以直接输出每个线程的执行情况. 线程的6种状态 超时等待状态和等待状态的区别: 超时等待状 ...
- JVM 调优 2:GC 如何判断对象是否为垃圾,三色标记算法应用原理及存在的问题?
文章目录 前言 一.如何判断一个对象是否为垃圾? 1.1.reference count(引用计数) 1.2.reference count(引用计数)存在的问题 二.Root Searching(根 ...
- java知识点8——垃圾回收原理和算法、通用的分代垃圾回收机制、 JVM调优和Full GC、开发中容易造成内存泄露的操作
垃圾回收原理和算法 内存管理 Java的内存管理很大程度指的就是对象的管理,其中包括对象空间的分配和释放. 对象空间的分配:使用new关键字创建对象即可 对象空间的释放:将对象赋值null即可 垃圾回 ...
- JVM从入门到精通(七):GC常用参数,Method Area,JVM调优案例分析
GC常用参数 -Xmn -Xms -Xmx -Xss 年轻代 最小堆 最大堆 栈空间 -XX:+UseTLAB 使用TLAB,默认打开 -XX:+PrintTLAB 打印TLAB的使用情况 -XX:T ...
- jvm原理及性能调优系列(jvm调优)
jvm原理及性能调优系列(jvm调优) JVM设置: 1.设置合适的最大堆内存(新生代和老生代的最大和值)和最小堆内存(jvm启动时占用的操作系统内存大小),及设置好堆的比例分配. 2.设置合适的新生 ...
- JVM调优,面到了阿里性能优化师!
小K 菜哥,我看你朋友圈,你好像换工作了? 菜哥 对啊,前阵子被产品经理烦的头疼,就想换工作了.刚好找到一个不错的. 小K 给我说说呗,让我也参考一下,我现在工资才15K,主管死坑,我也想换工作了 菜 ...
- 面试又栽在JVM调优上了!
很多人都是抱着旁观者的心态看关于jvm的文章,给个镜子看看你们的嘴脸- 那我今天要来和你们过过招了,前几天我在知乎上看到一个叫做为什么要学习jvm的话题下回答虽然寥寥无几,却成了大型打脸现场... 想 ...
最新文章
- Windows 64位机上C/C++代码静态检查工具Logiscope RuleChecker的安装和使用
- java transient关键字_小伙子,你真的搞懂 transient 关键字了吗?
- MVC 源码系列之路由(一)
- Apache Hadoop版本详解
- Win10 使用minikube搭建k8s集群 并运行hello-minikube实例
- Linux下CMake简明教程(五)正规一点的组织结构
- mac 使用brew卸载安装node
- shu函数php,【函数分享】每日PHP函数分享(2021-3-3)
- 【漫画详解】用iframe障眼法,骗取用户点击
- 解决pre-commit hook failed (add --no-verify to bypass)的问题
- R60笔记本电脑风扇清理加油过程
- WordPress纯代码纯静态开启七牛CDN并集成七牛缩略图和水印功能
- 全球最专业的技术媒体,如何复盘 2019 AI 的发展?
- 【天天读书】2023 年,科技行业的创业者们推荐这 47 本书 | 创始人书单
- bzoj1022 约翰的游戏 反SG-博弈
- 华为云ECS下安装MySQL
- Real World Games Look Like Spinning Tops (DeepMind NIPS2020) 论文阅读记录
- oracle数据库主机CPU使用率高问题的分析及SQL优化
- linux硬件级虚拟机系统 电脑安桌游戏多开完全去除vm标识去虚拟化
- 《乔布斯传》圈点(末篇)
热门文章
- 采宝支付携手 - 打造O2O支付全新生态
- 人工智能和机器学习之间的区别
- php集成微信支付后台app端
- .NET/C# 解压 Zip 文件时出现异常:System.IO.InvalidDataException: 找不到中央目录结尾记录。
- linux系统取消休眠,Linux关闭休眠和屏保模式
- 给React初学者的10分钟ES6教程
- NB-IoT智慧电表解决方案
- 第78届中国教育装备展示会即将在重庆开幕,亮点来了!
- 筑起网络信息安全防护
- 自闭症是广告敏感词?_我帮助建立了一个向自闭症儿童教授手语的机器人。 这是我学到的。...