JAVA运行时问题诊断-工具应用篇
该BLOG内容是之前在部门组织讨论运行时问题时自己写的PPT内容,内容以点带面,主要是方便以后自己回顾查看。
大纲包括:1、运行时问题分类 2、服务器自带工具 3、其他工具 4、例子 5、实际情况
运行时问题分类-软件角度:1、内存泄漏,对象未释放 2、线程阻塞、死锁 3、线程死循环 4、网络IO连接超时时间过长 5、磁盘不可写 .....
运行时问题分类-硬件角度:1、内存占用高 2、CPU占用高 3、网络无反应 4、硬盘空间满 ....
Linux指令:1、top, top -Hp pid 2、free 3、df 4、netstat, netstat -natp ...
JDK指令:1、jps, jps -v 2、jstack, jstack pid 3、jmap, jmap -dump:format=b,file=/opt/... 4、jstat, jstat -gcutil(gc,gccapacity) pid ....
工具:
实时分析工具: 1、Jconsole 2、VisualVM 3、JProfiler 4、JavaMelody 5、LambdaProbe ....
离线分析工具: 1、MemoryAnalyzer tool 2、Thread Dump Analyzer ....
DEMO:1、内存溢出 2、CPU占用过高 3、线程死锁 4、线程阻塞
准备工作:堆栈内存设置低一点,打印GC日志和OOM时输出dump文件: set JAVA_OPTS=-server -Xms24m -Xmx50m -XX:PermSize=28M -XX:MaxPermSize=80m -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:\temp\dump
内存溢出:
Map<String, Person> map = new HashMap<String, Person>();
Object[] array = new Object[];
for (int i = ; i < ; i++) {
String d = new Date().toString();
Person p = new Person(d, i);
map.put(i + "person", p);
array[i] = p;
}
MAT-关键字(个人理解,不一定准确):
Histogram:内存中的类对象实例的对象的个数和大小
Dominator Tree:堆对象树,对象大小和占用百分比
Leak Suspects:MAT分析的内存泄漏的可疑点
shallow heap:对象自身占用内存大小
retained heap:对象自身和引用的对象占用内存大小
Merge Shortest Paths to GC Roots:从GC根节点到该对象的路径视图
with outgoing references:对象持有的外部对象引用
with incomming references:对象被哪些外部对象引用
....
CPU占用过高:
int i = 0;
while (i < 1000000) {
i++;
System.out.println(i);
try {
Thread.sleep(0);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
线程死锁:
Thread t1 = new Thread(new SyncThread(obj1, obj2), "t1");
Thread t2 = new Thread(new SyncThread(obj2, obj1), "t2"); t1.start();
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t2.start();
synchronized (obj1) {
System.out.println("主线程 lock on " + obj1.getName());
}
private Person obj1;
private Person obj2; public SyncThread(Person o1, Person o2) {
this.obj1 = o1;
this.obj2 = o2;
} public void run() {
String name = Thread.currentThread().getName();
System.out.println(name + " acquiring lock on " + obj1.getName());
synchronized (obj1) {
System.out.println(name + " acquired lock on " + obj1.getName());
work();
System.out.println(name + " acquiring lock on " + obj2.getName());
synchronized (obj2) {
System.out.println(name + " acquired lock on " + obj2.getName());
work();
}
System.out.println(name + " released lock on " + obj2.getName());
}
System.out.println(name + " released lock on " + obj1.getName());
System.out.println(name + " finished execution.");
} private void work() {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
线程阻塞:
WaitThread thread1 = new WaitThread();
thread1.setName("线程1");
NotifyThread thread2 = new NotifyThread();
thread2.setName("线程2"); thread1.start(); try {
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
} thread2.start();
public class NotifyThread extends Thread {
@Override
public void run() {
synchronized (RequestThreadWait.object) {
System.out.println("线程" + Thread.currentThread().getName() + "占用了锁");
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
RequestThreadWait.object.notify();
System.out.println("线程" + Thread.currentThread().getName() + "调用了object.notify()");
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("线程" + Thread.currentThread().getName() + "释放了锁");
}
}
public class WaitThread extends Thread { public void run() {
synchronized (RequestThreadWait.object) {
System.out.println("线程" + Thread.currentThread().getName() + "获取到了锁开始");
try {
RequestThreadWait.object.wait();
} catch (InterruptedException e) {
}
System.out.println("线程" + Thread.currentThread().getName() + "获取到了锁结束!");
}
}
}
线程状态(个人理解,不一定准确):
WAITING (parking):线程自身挂起等待,正常
WAITING (on object monitor):线程主动执行wait,等待资源,如果是自己的程序,需要关注
BLOCKED (on object monitor):线程阻塞,等待对方释放资源,如果是互相等待对方阻塞的线程,则发生死锁
TIMED_WAITING (on object monitor):线程调用了wait(long timeout),在特定时间内等待
TIMED_WAITING (sleeping):调用了sleeping,休眠一段时间
JavaMelody:
LambdaProbe
实际情况:
用户反馈各种千奇百怪的问题!
网络访问连接不上
网站、接口访问超时
特定功能很慢
部分功能部分人打不开
.......
->
ping,telnet,traceroute....
top,top -Hp pid,jstack pid....
jstat -gc,gcutil,gccapacity pid...
jmap -dump:format=b,file=/opt/.... tail, df -lh....
netstat -natp....
.....
生产问题没有统一解决办法,具体问题具体分析
内存查看:jstat
线程情况查看:top -Hp pid
CPU查看:jstack
网络查看:netstat
实际问题分析:
线上查看 服务器情况分析 获取内存dump 获取javacore
线下分析 工具调试分析内存线程
代码调试 Eclipse Class Decompiler(自动反编译,选择JD-Core,精确行数)
...
转载请注明:http://lawson.cnblogs.com
上面是实际生产问题的自己写的PPT,copy下来的,JDK自带的工具和指令比较强大,本篇文章没有太多介绍。
JAVA运行时问题诊断-工具应用篇的更多相关文章
- java运行时内存模式学习
学习java运行时内存模式: 各区介绍: 方法区(线程共享):用于存放被虚拟机加载的类的元数据:静态变量,常量,以及编译和的代码(字节码),也称为永久代(所有该类的实例被回收,或者此类classLoa ...
- Jvm基础(1)-Java运行时数据区
最近在看<深入理解Java虚拟机>,里面讲到了Java运行时数据区,这是Jvm基本知识,把读书笔记记录在此.这些知识属于常识,都能查到的,如果我有理解不对的地方,还请指出. 首先把图贴上来 ...
- Android PermissionUtils:运行时权限工具类及申请权限的正确姿势
Android PermissionUtils:运行时权限工具类及申请权限的正确姿势 ifadai 关注 2017.06.16 16:22* 字数 318 阅读 3637评论 1喜欢 6 Permis ...
- Windows7下Java运行时环境搭建
第一步:下载JDK 地址:http://www.oracle.com/technetwork/java/javase/downloads/index.html,(由于Sun于2009年被oracle收 ...
- Rhino+envjs-1.2.js 在java运行网站js 工具类
java爬虫遇到个页面加密的东西,找了些资料学习学习 做了个java运行js的工具类,希望对大家有用,其中用到client(获取js)可以自行换成自己的client.主要是用了 Rhino就是Java ...
- Java运行时内存
对于java程序员来说,并不必显示地对内存进行管理,一切都交给java虚拟机去做吧,而且,你也不一定做得比java虚拟机来得专业.好像所有内存管理都交给虚拟机去做就万事大吉了,但是,事实有时并非如此, ...
- 读书笔记-浅析Java运行时数据区
作为一个 Java 为主语言的程序员,我偶尔也需要 用 C/C++ 写程序,在使用时让我很烦恼的一件事情就是需要对 new 出来的对象进行 delete/free 操作,我老是担心忘了这件事情,从而导 ...
- Java运行时环境---内存划分
背景:听说Java运行时环境的内存划分是挺进BAT的必经之路. 内存划分: Java程序内存的划分是交由JVM执行的,而不像C语言那样需要程序员自己买单(C语言需要程序员为每一个new操作去配对del ...
- JVM发展史和Java运行时内存区域
目前三大主流JVM: Sun HotSpot:Sun于1997年收购Longview Technologies公司所得.Sun于2009年被Oracle收购. BEA JRockit:BEA于2002 ...
随机推荐
- Django基础,Day4 - views 详解
在Django中,网页和其他内容是通过视图传递的.每个视图由一个简单的Python函数表示,Django将通过检查请求的URL(准确地说,是域名后面的部分URL)来选择一个视图. 例如,用户在浏览器中 ...
- 浅谈Android样式开发之selector
引言 上一篇Android UI中文章我们详细介绍了Android中shape标签的使用.通过shape标签我们可以定义矩形.椭圆.环形.直线等效果.不过shape只能定义单一的形状,在实际开发中,我 ...
- asp.net MVC4 异步文件上传
1.下载ajaxfileupload.js 2.在控制器内创建如下方法 //文件上传 public ActionResult uploadFile(HttpPostedFileBase file) { ...
- AngularJS 依赖注入
依赖注入(Dependency Injection,简称DI)是一种软件设计模式,在这种模式下,一个或更多的依赖(或服务)被注入(或者通过引用传递)到一个独立的对象(或客户端)中,然后成为了该 ...
- Standard C 语言标准函数库介绍
全面巩固所知所学,往精通方向迈进! Standard C 语言标准函数库速查 (Cheat Sheet) from:http://ganquan.info/standard-c/function/ C ...
- Android之仿微信图片选择器
先上效果图.第一张图显示的是“相机”文件夹中的所有图片:通过点击多张图片可以到第二张图所示的效果(被选择的图片会变暗,同时选择按钮变亮):点击最下面的那一栏可以到第三张图所示的效果(显示手机中所有包含 ...
- gulp 实现 js、css,img 合并和压缩
前提条件,知道如何安装nodejs.gulp,这里不做介绍,可以自行google 实现此功能需要安装的gulp工具有如下 npm install gulp-htmlmin gulp-imagemin ...
- Bookshop(一)数据库连接
连接池配置文件db.properties配置 1.新建一个普通文件->改名为db.properties(后缀)手动添加属性 一般为数据库驱动类.数据库连接地址.用户名.用户密码 driver=c ...
- mac 下配置 git
http://www.cnblogs.com/chenlogin/p/5124318.html
- iOS开发 Xcode8中遇到的问题及改动
iOS开发 Xcode8中遇到的问题及改动 新版本发布总会有很多坑,也会有很多改动. 一个一个填吧... 一.遇到的问题 1.权限以及相关设置 iOS10系统下调用系统相册.相机功能,或者苹果健康 ...