JVM异常退出原因追踪

标签: jvm 异常 原因 | 发表时间:2016-03-11 14:05 | 作者:supben
出处:http://www.iteye.com
package com.xx;

import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.LockInfo;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MonitorInfo;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.util.ArrayList;
import java.util.List;

public class Test{
	static {
		/**
		 * 打印JVM退出堆栈信息
		 */
		jvmExitHook();
	}

	public static void jvmExitHook() {
		System.out.println("注册JVM Shutdown钩子方法---------");
		Runtime.getRuntime().addShutdownHook(new Thread() {
			@Override
			public void run() {
				MemoryMXBean memorymbean = ManagementFactory.getMemoryMXBean();
				System.out.println("####################内存信息####################");
				System.out.println("Heap Memory: " + memorymbean.getHeapMemoryUsage());
				System.out.println("Non Heap Memory: " + memorymbean.getNonHeapMemoryUsage());

				List<GarbageCollectorMXBean> list = ManagementFactory.getGarbageCollectorMXBeans();
				if (list != null && list.size() > 0) {
					System.out.println("####################Gc信息####################");
					for (GarbageCollectorMXBean gcBean : list) {
						String s = "gc name=" + gcBean.getName() + ",gc count=" + gcBean.getCollectionCount() + ",gc time=" + gcBean.getCollectionTime();
						System.out.println(s);
					}
				}

				ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
				long[] ids = threadBean.getAllThreadIds();
				System.out.println("####################线程信息####################");
				for (long id : ids) {
					ThreadInfo threadInfo = threadBean.getThreadInfo(id, Integer.MAX_VALUE);
					if (threadInfo != null) {
						String s = "blockcount=" + threadInfo.getBlockedCount() + ",blocktime=" + threadInfo.getBlockedTime();
						s = s + ",waitedcount=" + threadInfo.getWaitedCount() + ",waitedtime=" + threadInfo.getWaitedTime();
						System.out.println(s);
						System.out.println(getThreadInfo(threadInfo));
					}
				}

				long[] deadlock_ids = threadBean.findDeadlockedThreads();
				if (deadlock_ids != null) {
					System.out.println("####################死锁信息####################");
					for (long id : deadlock_ids) {
						System.out.println("死锁的线程号:" + id);
					}
				}
			}

		});
	}

	public static String getThreadInfo(ThreadInfo t) {

		try {
			StringBuilder sb = new StringBuilder("\"" + t.getThreadName() + "\"" + " Id=" + t.getThreadId() + " " + t.getThreadState());
			if (t.getLockName() != null) {
				sb.append(" on " + t.getLockName());
			}
			if (t.getLockOwnerName() != null) {
				sb.append(" owned by \"" + t.getLockOwnerName() + "\" Id=" + t.getLockOwnerId());
			}
			if (t.isSuspended()) {
				sb.append(" (suspended)");
			}
			if (t.isInNative()) {
				sb.append(" (in native)");
			}
			sb.append('\n');
			int i = 0;
			for (StackTraceElement ste : t.getStackTrace()) {
				sb.append("\tat " + ste.toString());
				sb.append('\n');
				if (i == 0 && t.getLockInfo() != null) {
					Thread.State ts = t.getThreadState();
					switch (ts) {
					case BLOCKED:
						sb.append("\t-  blocked on " + t.getLockInfo());
						sb.append('\n');
						break;
					case WAITING:
						sb.append("\t-  waiting on " + t.getLockInfo());
						sb.append('\n');
						break;
					case TIMED_WAITING:
						sb.append("\t-  waiting on " + t.getLockInfo());
						sb.append('\n');
						break;
					default:
					}
				}

				for (MonitorInfo mi : t.getLockedMonitors()) {
					if (mi.getLockedStackDepth() == i) {
						sb.append("\t-  locked " + mi);
						sb.append('\n');
					}
				}
			}
			if (i < t.getStackTrace().length) {
				sb.append("\t...");
				sb.append('\n');
			}

			LockInfo[] locks = t.getLockedSynchronizers();
			if (locks.length > 0) {
				sb.append("\n\tNumber of locked synchronizers = " + locks.length);
				sb.append('\n');
				for (LockInfo li : locks) {
					sb.append("\t- " + li);
					sb.append('\n');
				}
			}
			sb.append('\n');
			return sb.toString();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";
	}
}

 

 找一个类,启动的时候注册进去JVM退出的钩子方法

由于ThreadInfo默认只打出8行堆栈内容,可能会错过我们需要的报错信息。所以改写了toString方法



已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [jvm 异常 原因] 推荐:

JVM异常退出原因追踪

- - 编程语言 - ITeye博客
System.out.println("注册JVM Shutdown钩子方法---------");. System.out.println("####################内存信息####################");. System.out.println("####################Gc信息####################");.

JVM中的异常处理

- - BlogJava-首页技术区
欢迎来到“ Under The Hood”第六期. 本期我们介绍 JVM处理异常的方式,包括如何抛出和捕获异常及相关的字节码指令. 但本文不会讨论finally子句,这是下期的主题. 你可能需要阅读 往期的文章才能更好的理解本文. 在程序运行时,异常让你可以平滑的处理意外状况. 为了演示JVM处理异常的方式,考虑NitPickyMath类,它提供对整数进行加,减,乘,除以及取余的操作.

深入了解JVM笔记(1)—内存区域与内存溢出异常

- - 博客园_首页
  在前面的几篇博文中,我们一起简单的了解jvm的基本知识,例如jvm对字符串的处理等等,或许大家看完后就把这当成一条准则来记住了,但是一些比较好奇的朋友有没有想过,这是为什么呢. 下面就让我们开始一步一步的深入学习.   在这篇博文中呢,我打算主要就讲Java内存区域与内存溢出异常吧. 1.Java虚拟机运行时数据区.

JVM研究

- - 开源软件 - ITeye博客
每天接客户的电话都是战战兢兢的,生怕再出什么幺蛾子了. 我想Java做的久一点的都有这样的经历,那这些问题的最终根结是在哪呢. JVM全称是Java Virtual Machine,Java虚拟机,也就是在计算机上再虚拟一个计算机,这和我们使用 VMWare不一样,那个虚拟的东西你是可以看到的,这个JVM你是看不到的,它存在内存中.

jvm调优

- - 互联网 - ITeye博客
printf "%x\n" 21742  找到耗时最长的进程. jstack pid | grep 54ee  定位某个类的方法. jstack 10535|grep -A 10 2a1d (最后十行). jmap 查询pid 内存线程. 附:TOP命令中需要关注的值:. (1)load average:此值反映了任务队列的平均长度;如果此值超过了CPU数量,则表示当前CPU数量不足以处理任务,负载过高.

网站流量异常变动的8种常见原因

- Demi - 蓝鲸的网站分析笔记
网站分析中,最常见的一项工作就是对流量的异常变化进行分析和解释.今天网站的流量变高了,为什么. 后天网站的流量降低了,又是为什么. 对网站有什么影响?这些都是等待我们去回答的问题. 蓝鲸网站分析笔记 Original Source. 通常在遇到这种情况时,我们会先进行定量分析,通过细分找出具体发生异常变化的那部分流量.然后再进行定性分析,找出这部分流量发生异常变化的具体原因.第一步的工作相对简单一些,通过google analytics的细分功能逐层剖析,就可以找到原因.而第二步的工作就有些难度了.因为数据本身只能说明发生了什么,却不能告诉我们为什么,所以,真正的原因需要我们自己去寻找..

Redis持久化文件异常原因以及修复方法

- - 丕子
上线了Redis的模块,昨天Redis Server重启了,但是Redis Instance起不来了,同学联系我,我也不知道具体情况,就猜了几个原因:1、持久化文件可能太大,没load完,所以短时间内启动不了.  2、主从配置文件被sentinel修改乱了. 最后查了下原因,是由于机房突然断电导致redis aof持久化文件写入异常,这个问题详见: link.

学习JVM的References

- LightingMan - 淘宝JAVA中间件团队博客
本blog中列举了我学习JVM的references,会不断的更新,为了避免版权问题,就不在blog上提供references的下载了,感兴趣的同学可自行下载或购买,:). |— [ Hotspot GC论文 ]. |— [ 其他JVM GC ]. |— Linux内核源代码情景分析. |— Linux 内核中断内幕.

深入理解JVM

- 小伟 - ITeye论坛最新讨论
1   Java技术与Java虚拟机. 说起Java,人们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成: Java编程语言、Java类文件格式、Java虚拟机和Java应用程序接口(Java API). 图1   Java四个方面的关系. 运行期环境代表着Java平台,开发人员编写Java代码(.java文件),然后将之编译成字节码(.class文件).

jvm垃圾回收

- Cano - 淘宝共享数据平台 tbdata.org
在jvm中堆空间划分为三个代:年轻代(Young Generation)、年老代(Old Generation)和永久代(Permanent Generation). 年轻代和年老代是存储动态产生的对象. 永久带主要是存储的是java的类信息,包括解析得到的方法、属性、字段等等. 我们这里讨论的垃圾回收主要是针对年轻代和年老代.