性能监控工具以及java堆分析OOM
一、性能监控工具
1.系统性能监控
Linux
-确定系统运行的整体状态,基本定位问题所在
-uptime:
------系统时间
------运行时间(例子中为127天)
------连接数(每个终端算一个连接)
------1,5,15分钟内的系统平均负载(运行队列中的平均进程数)
-top命令:动态查看进程变化,监控linux的系统状况
-vmstat:显示虚拟内存状态(“Viryual Memor Statics”),但是它可以报告关于进程、内存、I/O等系统整体运行状态,如果CPU占用很高,上下文切换频繁,说明系统有现成正在频繁切换
-pidstat:监控全部或指定进程占用系统资源的情况
------细致观察进程
------需要安装:sudo apt-get install sysstat
------监控CPU
------监控IO
------监控内存
pidstat –p 2962 –u 1 3 -t
-p指定进程号,-u监控CPU 1秒采样 一共3次、-t显式线程
Windows
-Perfmon
------Windows自带多功能性能监控工具
-Process Explorer(进程浏览器)
-pslist(需要下载PSTOOLS)
https://docs.microsoft.com/zh-cn/sysinternals/downloads/pstools
------命令行工具,可用于自动化数据收集,显式java程序的运行情况
2.java自带的工具
查看java程序运行细节,进一步定位问题
-jps:列出java进程,类似于ps命令
------参数-q可以指定jps只输出进程ID,不输出类的短名称
------参数-m可以用于输出传递给java进程(主函数)的参数
------参数-l可以用于输出主函数的完整路径
------参数-v可以显示传递给jvm的参数
-jinfo:用来查看正在运行的java应用程序的扩展参数,甚至支持在运行时,修改部分参数
------ -flag<name>: 打印指定JVM参数值
------ -flag[+|-]<name>:设置指定JVM参数的布尔值
------ -flag<name>=<value>:设置指定JVM参数的值
-jmap:生成java应用程序的堆快照和对象的统计信息
------ jmap -histo 1536 >e:\project\JVM\s.txt
-Dump堆
------ jmap -dump:format=b,file=e:\project\JVM\heap.hprof 6900
-jstack:打印线程dump
------ -l打印锁信息
------ -m 打印java和native的帧信息
------ -F 强制dump, 当jstack没有响应时使用
jstack 6900 >> e:\project\JVM\a.txt
线程id号tid都是16进制
-JConsole
------图形化监控工具
------可以查看java应用程序的运行情况,监控堆信息,永久区使用情况,类加载等
-Visual VM
------是一个功能强大的多合一故障诊断和性能监控的可视化工具
二、java堆分析
1.内存溢出(OOM)的原因
-在jvm中,有哪些内存区间
------ 堆,永久区,线程栈,直接内存
------ 线程栈,是操作系统分配给jvm的一块内存区域,虽然说不在堆里面,但是这几块区域的总大小,不能超过操作系统能够分配给jvm的内存空间,一般32位系统,不能超过2g,当然肯定不能超过计算机的物理内存。
------ 如果上述四块内存区域,只要有一块申请的空间不能得到满足,那么就可能引起内存溢出(OOM)
------ 堆溢出
| 
 import java.util.ArrayList; public class TestHeapOOM { public static void main(String[] args) { ArrayList<byte[]> list = new ArrayList<byte[]>(); for(int i = 0; i < 1024 * 1024; i++) { list.add(new byte[1 * 1024 * 1024]); } } }  | 
| 
 占用大量堆空间,直接溢出--------解决:增大堆空间,及时释放内存  | 
------永久区OOM(使用cglib进行测试,由于环境问题,没有做测试,就截了视频的图)
| 
 public class TestPerGenOOM{ public static void main(String[] args){ for(int i = 0; i < 100000; i++){ CglibBean bean = new CglibBean("****", new HashMap()); } } } 解决方法:增大perm区,允许class原数据回收  | 
------java栈溢出
这里的栈溢出指,在创建线程的时候,需要为线程分配栈空间,这个栈空间是向操作系统请求的,如果操作系统无法给出足够的空间,就会抛出OOM
| 
 操作系统可分配  | 
|
| 
 堆空间  | 
 线程栈空间  | 
| 
 public class TestStackOOM implements Runnable{ public void run(){ try{ Thread.sleep(10000000); }catch(Exception e){ e.printStackTrace(); } } public static void main(String[] args){ for(int i = 0; i < 10000000; i++){ new Thread(new TestStackOOM(), "Thread" + 1).start(); System.out.println("Thread" + i + " created"); } } } 一直不会触发内存溢出 ,视频中是 Exception in thread ”main” java.lang.OutOfMemoryError;unable to create new native thread. 解决方法:减少堆内存,减少线程栈的大小(每个线程拥有线程栈,如果栈大小越小,那么在总空间一定的情况下,就能创建更多线程 )  | 
|
------直接内存溢出(ByteBuffer.allocateDirect()无法从操作系统中获取足够空间)
| 
 操作系统可分配  | 
||
| 
 堆空间  | 
 线程栈空间  | 
 直接内存  | 
| 
 import java.nio.ByteBuffer; public class TestDirectOOM { public static void main(String[] args) { for(int i = 0; i < 1024; i++){ ByteBuffer.allocateDirect(1024 * 1024); System.out.println(i); System.gc(); } } } java -Xmx1g -XX:+PrintGCDetails TestDirectOOM 依然没有发生内存溢出,搞不清原因,截了视频的图 新生代,老年代都没有使用过多,基本可以断定是直接内存出问题 解决方法:减少堆内存,有意触发GC  | 
||
2.支配树、浅堆、深堆
-浅堆:一个对象所占用的内存大小
浅堆(Shallow Heap)是指一个对象所消耗的内存。在32位系统中,一个对象引用会占据4个字节,一个int类型会占据4个字节,long型变量会占据8个字节,每个对象头需要占用8个字节。下面以String为例
2个int值共占8字节,对象引用占用4字节,对象头8字节,合计20字节,向8字节对齐,也就是8的倍数,故占24字节
这24字节为String对象的浅堆大小。它与String的value实际取值无关,无论字符串长度如何,浅堆大小始终是24字节
深堆:一个对象被GC回收后,可以真实释放的内存大小
了解深堆,首先需要了解保留集,对象A的保留集指当对象A被垃圾回收之后,可以被释放的所有对象的集合(包括对象A本身),即只能通过对象A被直接或间接访问到的所有对象的集合(包括A),被访问的对象入度为1,且这个1就是A或者A间接访问的对象。
----只能通过对象访问到的(直接或间接)所有对象的浅堆之和(支配树)
另外一个概念,对象的实际大小,定义为一个对象所能触及的所有对象的浅堆大小之和
上图中,A的浅堆大小只是A本身,不含C和D,而实际大小是ACD三者之和。而A的深堆大小为A与D之和,因为C还有B的引用。
支配树
左图表示对象引用图,右图表示左图所对应的支配树。对象A和B由根对象直接支配,由于在到对象C的路径中,可以经过A,也可以经过B,因此对象C不能被A和B支配,所以它的直接支配者也是根对象。对象F与对象D相互引用,因为到对象F的所有路径必然经过对象D,因此,对象D是对象F的直接支配者。而到对象D的所有路径中,必然经过对象C,即使是从对象F到对象D的引用,从根节点出发,也是经过对象C的,所以,对象D的直接支配者为对象C;同理,对象E支配对象G。到达对象H的可以通过对象D,也可以通过对象E,因此对象D和E都不能支配对象H,而经过对象C既可以到达D也可以到达E,因此对象C为对象H的直接支配者。
支配者被回收,被支配对象也会被回收
性能监控工具以及java堆分析OOM的更多相关文章
- 深入理解JVM(八)——java堆分析
		
上一节介绍了针对JVM的监控工具,包括JPS可以查看当前所有的java进程,jstack查看线程栈可以帮助你分析是否有死锁等情况,jmap可以导出java堆文件在MAT工具上进行分析等等.这些工具都非 ...
 - JVM学习--(八)java堆分析
		
上一节介绍了针对JVM的监控工具,包括JPS可以查看当前所有的java进程,jstack查看线程栈可以帮助你分析是否有死锁等情况,jmap可以导出java堆文件在MAT工具上进行分析等等.这些工具都非 ...
 - 深入理解JVM一java堆分析
		
上一节介绍了针对JVM的监控工具,包括JPS可以查看当前所有的java进程,jstack查看线程栈可以帮助你分析是否有死锁等情况,jmap可以导出java堆文件在MAT工具上进行分析等等.这些工具都非 ...
 - JVM内核-原理、诊断与优化学习笔记(八):JAVA堆分析
		
文章目录 内存溢出(OOM)的原因 在JVM中,有哪些内存区间? 堆溢出 永久区 Java栈溢出 直接内存溢出 小问题? MAT使用基础 柱状图显示 支配树 显示线程信息 显示堆总体信息,比如消耗最大 ...
 - java堆分析神器MAT
		
Memory Analyzer(MAT) 基于Eclipse的软件 http://www.eclipse.org/mat/
 - Java堆分析
 - (转载)Java自带的GUI性能监控工具Jconsole以及JisualVM简介
		
原文链接:http://blog.csdn.net/chendc201/article/details/22905503 1 Jconsole 1.1 简介以及连接 JConsole是一个基于JMX的 ...
 - Java虚拟机常用的性能监控工具
		
基础故障处理工具 jps: 虚拟机进程状况工具 功能:来处正在运行的虚拟机进程,并显示虚拟机执行主类名称,以及本地虚拟机唯一ID. 它是使用频率最高的命令行工具,因为其他JDK工具大多需要输入他查询到 ...
 - JProfiler - Java的性能监控工具
		
简介 JProfiler是一款Java的性能监控工具.可以查看当前应用的对象.对象引用.内存.CPU使用情况.线程.线程运行情况(阻塞.等待等),同时可以查找应用内存使用得热点,即:哪个对象占用的内存 ...
 
随机推荐
- 第三组 通信一班 030  OSPFv2、OSPFv3综合实验
			
一. 实验目的 掌握 OSPFv2. OSPFv3 的配置方法 掌握在帧中继环境下OSPFv2. OSPFv3 的配置方法 掌握 OSPFv2. OSPFv3 NSSA 的配置方法 ...
 - VSTO:使用C#开发Excel、Word【13】
			
应用程序对象的操作本章将介绍从Application对象开始的Excel对象模型中的一些主要对象. Excel对象模型中的主要对象有许多方法和属性,完全描述这些对象超出了本书的范围.相反,本章重点介绍 ...
 - Python基础10_函数
			
直接贴笔记 : #!/usr/bin/env python # coding:utf-8 # 定义函数时要写成良好的注释习惯 通常用三个单引号 def test(x): ''' 计算一个y=2*x+1 ...
 - 在linux系统安装tomcat后,bin文件下startup.sh启动不
			
Linux里的tomcat下的 bin ,没法执行, 可直接到 bin 目录下 ,执行 chmod 777 * 就可以了. [srmdev@mvxl0793 bin]$ chmod 777 * ...
 - QT | QT MSVC 2015 + VS 2015开发环境配置及GIT设置
			
1.下载: 所有Qt版本的下载地址: http://download.qt.io/archive/qt/ 实际使用了http://download.qt.io/archive/qt/5.7/5.7.1 ...
 - 利用maven的profiles灵活的配置多环境
			
<!--多环境配置--> <profiles> <profile> <id>dev</id> <activation> < ...
 - 初窥async,await
			
首先是一道今日头条的面试题:(听说是今日头条的并且已经烂大街了) async function async1() { console.log( 'async1 start' ) await async ...
 - excle中如何将一串数字前后加上单引号
			
1.新建excle表 2.构造如下一串字母加数字的字符串: 3.在B1栏中输入="“"&A1&"”",展示效果如下:
 - XML二
			
XML的语法要求: 1,XML文档必须有一个顶层元素,即文档元素,所有其他元素必须嵌入在文档元素中. 2,元素嵌套要正确,即如果一个元素在另一个元素中开始,那么必须在同一个元素中结束. 3,每个元素必 ...
 - 《Linux内核原理与分析》第九周作业
			
课本:第八章 进程的切换和系统的一般执行过程 进行进程调度的时机 Linux内核通过schedule函数实现进程调度,schedule函数在运行队列中找到一个进程,把CPU分配给它 调用schedul ...