java se 6在solaris的可观察性特征分析
java se 6平台中提供了多种可观察性(observability)工具,这其中的许多工具都可在系统中运行,而这些工具中的只有极少数被用于挂起进程或核心复制处理。因此,在本文中,我们将分析这些可观察性工具在进程上的效果。
一、 在java se 6平台中的可观察性工具-dtrace
在java se 6软件中又引入了许多可观察性改进功能。尽管其中大多数可适用于所有的平台,但是其中的一些改进仅是特定于solaris操作系统(特别针对solaris 10及更高版本)的。在j2se 5.0平台中,引入了一种新的动态跟踪(dtrace)行为――jstack。正如我们已经了解的,jstack能够打印混合模式堆栈跟踪信息(java和本机c/c++语言是以帧方式显示的)。当从一个给定的java进程中发出pollsys系统调用时,下列d脚本将输出对混合模式堆栈的跟踪信息:
#!/usr/sbin/dtrace -s syscall::pollsys:entry / pid == $1 / { /*打印至多50帧*/ jstack(50); } |
下面是上面脚本的运行结果:
libc.so.1`__pollsys+0xa libc.so.1`poll+0x52 libjvm.so`int os_sleep(long long,int)+0xb4 libjvm.so`int os::sleep(thread*,long long,int)+0x1ce libjvm.so`jvm_sleep+0x1bc java/lang/thread.sleep dtest.method3 dtest.method2 dtest.method1 dtest.main [...篇幅所限,删去了一些输出结果...] |
其实,jstack就是java可观察性在solaris 10 os及以上版本中的一个很有用的起点。但是,java se 6中远不止这些,它新增加了许多针对java虚拟机(jvm)可观察性和java应用程序可观察性的dtrace probe。java se 6发行中增加两种jvm特定的dtrace提供者-hotspot和hotspot_jni。
二、 hotspot提供者
hotspot提供者增加了许多探针,它们可以大致地作如下分类:
? vm生命周期探针-vm启动,关闭事件
? 线程生命周期探针-线程启动,停止,等等
? 类加载探针-一个java类加载或卸载
? 垃圾收集探针-gc启动,结束
? 方法编译探针-java字节码-到-本机代码编译("hotspot编译")
? 监视器探针-java监视竞争性入口,通知,通知全部,等等
? 应用程序探针-java对象分配,java方法入口/返回,等等
有关于这些探针的更为详细的信息,请参考keith mcguigan的博客。下面是使用这些探针的一些示例。
(一) 打印java线程的名称
hotspot$1:::thread-start { self->ptr = (char*) copyin(arg0, arg1+1); self->ptr[arg1] = '/0'; self->threadname = (string) self->ptr; printf("thread %s started/n", self->threadname); } |
(二) 在d脚本中的-verbose:class等价物
你可能已经使用过-verbose:class jvm选项。当一个java类加载或卸载时,这个选项能够使jvm打印一个跟踪消息。下面是使用dtrace得到相同结果的情况:
/*当每个类加载时,打印出其各自的名称*/ hotspot$1:::class-loaded { self->str_ptr = (char*) copyin(arg0, arg1+1); self->str_ptr[arg1] = '/0'; self->name = (string) self->str_ptr; printf("class %s loaded/n", self->name); } |
(三) 打印异常中的栈跟踪信息(除了混合模式)
throwable.printstacktrace()方法打印一个包含java帧的堆栈跟踪。这个d脚本将打印java代码,java本机接口(jni)代码,c/c++代码以及os c/c++代码的所有的帧-无论何时引发一个例外。
hotspot$1:::method-entry { self->ptr = (char*)copyin(arg1, arg2+1); self->ptr[arg2] = '/0'; self->classname = (string)self->ptr; self->ptr = (char*)copyin(arg3, arg4+1); self->ptr[arg4] = '/0'; self->methodname = (string)self->ptr; } hotspot$1:::method-entry / self->classname == "java/lang/throwable" && self->methodname == "<init>" / { jstack(); } |
在java代码中的所有的异常和错误都直接或间接地派生自java.lang.throwable,因此所有的异常构造器最后都将调用java.lang.throwable的构造器。这个d脚本建立一个方法入口探针-使用一个针对该构造器的过滤器(注意,<init>是构造器方法的内部名)。当调用这个构造器时,jstack()行为将打印混合模式堆栈跟踪。
(四) java堆直方图
我们可以使用object-alloc探针来构建一个java堆直方图,如下所示:
hotspot$1:::object-alloc { self->str_ptr = (char*) copyin(arg1, arg2+1); self->str_ptr[arg2] = '/0'; self->classname = (string) self->str_ptr; @allocs_count[self->classname] = count(); @allocs_size[self->classname] = sum(arg3); } |
(五) hotspot_jni提供者
jni允许java程序与c/c++代码进行交互。如果你想观察java代码与本机代码的交互,你可以使用hotspot_jni提供者。对于每一个jni函数输入/输出而言,这个提供者将暴露一个探针。
(六) 在java程序中使用dtrace的效果
dtrace被设计为一种生产模式可观察性系统(未使用时具有零影响)。当支持探针时,被观察的系统不受影响。
由于大部分的由hotspot和hotspot_jni提供者所暴露的jvm探针都是轻量级的,因此可以用于生产机器中。然而,一些由hotspot提供者所暴露的探针要求使用一个特定的命令行选项"-xx:+extendeddtraceprobes"来启动jvm。这些探针分别是:java方法入口/方法返回,对象分配和java监视器探针。注意,这些探针都要求改变hotspot字节码解释器和hotspot编译器(字节码-到-机器代码编译器)。即使不被支持时,这些探针的代价也是比较昂贵的。 三、 在java se 6平台中的可观察性工具
除了dtrace与java技术的集成之外,java se 6发行中还包含了许多其它的可观察性工具。下面总结了这些工具,其中还包含一些更为详细的链接说明。
(一) jconsole
jconsole使用jvm的可扩展性java管理扩展(jmx)工具来提供关于运行于java平台的应用程序的性能和资源消耗的信息。
在j2se 5.0软件中,你需要启动使用-dcom.sun.management.jmxremote选项监控的应用程序。注意:在java se 6软件中,不再有这一要求。当启动该应用程序时,不需要特定的命令行选项。
在生产系统中的应用
jconsole启动一个在被观察的java程序的jvm内部的jmx代理。运行另外一部分代码仅有一点极微弱的影响-但是影响很小。
另外,尽管jconsole在监视本地应用程序的开发和快速原型开发中很有用,但在实际的应用系统中不推荐使用。理由是,jconsole本身也消耗大量的系统资源。我们推荐的方法是用远程监控来把jconsole应用程序与被监控的系统加以隔离。因此,对于应用系统来说,以远程模式使用jconsole更好些。对于安全的远程监控来说,可以使用安全选项。
(二) jps
jps相当于solaris进程工具ps。更多的信息,请参考《jps-java virtual machine process status tool》。
不象"pgrep java"或"ps -ef | grep java",jps并不使用应用程序名来查找jvm实例。因此,它查找所有的java应用程序,包括即使没有使用java执行体的那种(例如,定制的启动器)。另外,jps仅查找当前用户的java进程,而不是当前系统中的所有进程。
(三) jstat
jstat显示一个测量(instrumented)java hotspot虚拟机的性能统计信息(请参考《jstat-java virtual machine statistics monitoring tool》)。有关于性能计数器的更详细的信息请参考《code sample-jvmstat 3.0》。
(四) jstatd
jstatd是一个java远程方法调用(rmi)服务器应用程序-它监控测量java hotspot虚拟机的创建和终止并且提供一个接口来允许远程监控工具依附到运行于本地主机的jvm(请参考《jstatd-virtual machine jstat daemon》)。
在应用系统中的使用
jps及其它jvmstat实用程序都使用极为轻量级的观察机制。由jvm分配一小部分共享内存,而性能计数器也是从这部分内存中分配的。jvm子系统基于其感兴趣的事件更新性能计数器。客户端工具仅仅负责异步地从共享内存段中进行读取。因此,总的来说,使用jvmstat进行监控的效果是很小的。 四、 java se 6平台中针对于postmortem的可观察性工具
java se 6支持postmortem可观察性工具-它能够从挂起的java进程或java核心复制中获得信息。这些工具(除了jhat外)都使用solaris libproc库来依附到和读取被观察的程序。在观察期间,目标程序被挂起。当java进程被挂起或当从一个java进程中发生一个核心复制时,可以使用这些工具。在任何可能的情况下,请考虑使用gcore来捕获系统的核心复制的一个快照并且使用任何下列工具"离线"分析核心复制。
(一) jinfo
jinfo打印一个给定的java进程或核心文件或一个远程调试服务器的java配置信息。配置信息包括java系统属性和jvm命令行标志(更多信息,请参考《jinfo-configuration info》)。
(二) jmap
jmap:如果这个工具不使用任何选项(除了pid或core选项)运行,那么它显示类似于solaris的pmap工具所输出的信息。这个工具支持针对java堆可观察性的若干其它选项。
在java se 6平台中,新加入了一个-dump选项。这样可以使jmap能够把java堆信息复制到一个文件中,然后我们可以使用新的jhat命令(见下面一节)来分析它。
jmap -dump选项并不使用solaris libproc来实现实时处理;而是,它运行当前正运行的jvm中的一小段代码,由此来实现堆复制。既然这种堆复制代码运行于jvm内部,那么其速度是比较快的。堆复制的效果大致相当于实现一次"完全的gc"(对整个堆的垃圾收集),再加上把该堆的内容写入到文件中。实现堆复制的另外一种可能的思路是使用gcore来进行核心复制并且运行"jmap -dump"(这与以"离线"方式运行的核心复制形成对照)。
(三) jstack
jstack等价于solaris的pstack工具。jstack打印所有的java线程的堆栈跟踪信息(可选地包括本机帧信息),请参考《jstack-堆栈跟踪》。关于锁和死锁的信息也可以被打印,请参考java.util.concurrent locks。
(四) jsadebugd
jsadebugd依附到一个java进程或核心文件并且担当一个调试服务器的作用。远程客户,例如jstack、jmap和jinfo,都能够通过java rmi依附到该服务器。
(五) jhat
jhat是一个java堆复制浏览器。这个工具分析java堆复制文件(例如,由上面的"jmap -dump"所产生的)。jhat启动一个允许堆中的对象在web浏览器中进行分析的web服务器。这个工具并不是想用于应用系统中而是用于"离线"分析。"jhat工具是平台独立的",其意思是,它可以被用来观察在任何平台上所产生的堆复制。例如,我们有可能在linux系统上使用jhat来观察一个在solaris os上所产生的堆复制。
java se 6在solaris的可观察性特征分析的更多相关文章
- Monitor and diagnose performance in Java SE 6--转载
Java SE 6 provides an in-depth focus on performance, offering expanded tools for managing and monito ...
- 在 Java SE 6 中监视和诊断性能问题
Java™ Platform, Standard Edition 6 (Java SE) 专注于提升性能,提供的增强工具可以管理和监视应用程序以及诊断常见的问题.本文将介绍 Java SE 平台中监视 ...
- Java SE/EE/ME概念理解(Java版本发展历史)
继上一篇文章http://www.cnblogs.com/EasonJim/p/6181981.html中说的区别,其实分析的不够彻底,因此再次在这里做详细的分析. 零.Java与Sun.Oracle ...
- Using Headless Mode in the Java SE Platform--转
原文地址: By Artem Ananiev and Alla Redko, June 2006 Articles Index This article explains how to use ...
- Mac下打开eclipse 始终提示 你需要安装Java SE 6 Runtime
Mac下打开eclipse 始终提示 你需要安装Java SE 6 Runtime 周银辉 我的mac os 版本是10.9.2, JDK配置得好好的,但打开eclipse时还是提示需 ...
- mac下需要安装旧 Java SE 6 才能打开程序解决办法
今天我在mac系统下面安装myeclipse2014(myeclipse-pro-2014-GA-offline-installer-macosx.dmg)的时候,发现显示错误: 您需要安装旧 Jav ...
- ubuntu配置 Java SE 1.6
今天编译android 4.0时提示如下错误: You are attempting to build with the incorrect version of java. Your versi ...
- 《写给大忙人看的java se 8》笔记
现在才来了解java8,是不是后知后觉了点? 新的编程技术,个人不喜欢第一时间跟进. 待社区已有实践积淀再切入似乎更划算些? 一点点精明的考虑. 不多说,上代码. //读<写给大忙人看的java ...
- Java SE 基础:注释
Java SE 基础:注释 一.注释定义 用于解释说明程序的文字. 二.注释的作用 1.解释说明程序,提高程序的可读性 2.可以帮助我们调试程序:通过注释代码块,检测错误位置 三.格式 1.单行注释 ...
随机推荐
- ▲历史回眸--abbr和acronym的渊源
网景和微软的浏览器之战早已淡去多年,最终以微软的IE浏览器胜出,特别是IE6的出现,一度成为世界浏览器的霸主,至今无人能敌.去年IE6荣获“终身成就奖”,真是实至名归.本文涉及的两个标签abbr和ac ...
- 个人笔记--struts2对Action的权限拦截
一.编写一个类实现com.opensymphony.xwork2.interceptor.Interceptor 接口 PermissionInterceptor.java <pre name= ...
- spring mvc 配置
之前配置spring mvc 怎么都访不到对应的jsp,后来把prefix里面的jsp改为views,就能访问到了,然后再改回jsp也可以访问到 搞了两天,都崩溃了,不管怎样先把没问题的例子给记录下来 ...
- 用Thread类创建线程-2
支持原创,本系列文章均转自:http://www.blogjava.net/nokiaguy/category/38172.html 在Java中创建线程有两种方法:使用Thread类和使用Runna ...
- JavaScript 语言基础知识点总结
网上找到的一份JavaScript 语言基础知识点总结,还不错,挺全面的. (来自:http://t.cn/zjbXMmi @刘巍峰 分享 )
- [原博客] POJ 2484 A Funny Game
题目链接题意:有n个硬币排成一圈,两个人轮流操作,每次可以取走一个或者相邻的连个硬币(只算最开始相邻的,取之后才相邻的不算),问先手必胜还是必败. 这个题可以证明若n>=3,则先手必败.对称博弈 ...
- how to develop mobile web
http://blog.templatemonster.com/2010/05/11/how-make-mobile-website-6-easy-tips/ http://mobile.smashi ...
- webview调用javascript脚本无反应
最近遇到一个问题:在html中有一段javascript脚本定义了一个方法,在使用webview.loadUrl("javascript:方法名()")时方法未执行,后来 查资料发 ...
- 开始hadoop
hadoop介绍 分布式存储系统HDFS(Hadoop Distributed File System),提供了高可靠性.高扩展性和高吞吐率的数据存储服务: 资源管理系统YARN(Yet Anothe ...
- C++ Prime:const的引用
可以把引用绑定到const对象上,就像绑定到其他对象上一样,我们称之为对常量的引用.与普通引用不同的是,对常量的引用不能被用作修改它所绑定的对象: ; const int &r1 = ci; ...