性能是个很复杂的问题,尤其是当你意识到程序在编译阶段会经历多次重写的时候。首先,你的源码会被翻译成字节码,然后再被进一步编译成机器代码,有时候甚至是多次编译。
有时候你的程序运行得并不是很快。之后你就会抱怨你的平台或者工具,并且考虑用C或者什么奇怪的方式来重写系统中的关键部分。然而,在你开始这个黑暗过程之前,请先再看看:还有一些工具是能让你在享受着JVM便利的同时还把问题解决掉的。
如果充分发挥你对JVM内部以及JIT工作原理的知识,你可以优化你的程序让它执行得更快一些。但今天我们要讲的并不是这些优化本身。如果你对这些东西更感兴趣的话,可以看一个例子,”
HikariCP是如何优化的“。我们今天要讲的是一个叫
JITWatch的工具,你可以用它来查看JIT是如何去处理你的程序的。
JITWatch初瞥
JITWatch是Java Hotspot JIT编译器的一个日志分析工具。它会读入JIT的日志文件,然后将它的活动记录可视化。这个项目最初由Chris Newland发起,后面被捐赠给了Adopt OpenJDK这个项目。
如果你想知道JVM在运行时对你的代码做了什么或者需要调整JVM参数来优化虚拟机性能的时候,它可是个无价之宝。
除此之外,它还可以让你能同步地观察到程序的源码,字节码,以及机器代码,因此你不仅能更清楚应用的性能瓶颈,同时还能避免使用javap这样乱糟糟的命令行工具。先进的工具让生活变得更轻松,在这篇文章里,我们将给一个示例项目进行JITWatch的配置,并观察它在启动期间到底发生了什么。
开始JITWatch之旅
首先我们得获取下它的可执行程序。幸运的是,正如每一个有自尊心的软件一样,JITWatch也能在Github上获取到,这样前期的编译可以省掉了,我们可以直接拷贝一个。
git clone git@github.com:AdoptOpenJDK/jitwatch.git
cd jitwatch
mvn clean install -DskipTests=true
./launchUI.sh # make sure that line-endings are correct :)
完成之后,你会看到如下的漂亮的欢迎界面。
[img]http://zeroturnaround.com/wp-content/uploads/2014/07/welcomescreen-640x358.png”/>
很好,下面我们需要配置一下要研究的应用了。
这是我们要进行实验的小白鼠
我们希望每篇博客都能有不止一个用途,因此很快我们就面临了这样的问题:
我们应该运行一个什么样的DEMO工程,这样它能代表大多数的Java开发的应用?
根据我们的
Java工具及技术报告一文中所述,大多数人都是在进行WEB应用的开发,并且部署在Tomcat之上。 那看起来我们这个DEMO工程应该是一个WEB程序了。是的,你猜对了,它就是已使用多年的著名的Spring,我们将用它作为一个JRebel的DEMO程序来运行。
这里是它的
Github仓库地址,如果你希望拷贝一份修改一下的话。幸运的是,它是自我驱动的,因此我们什么都不用改就可以运行了。
mvn tomcat:run
它会在petclinic的父目录执行,并完成所有的事情,创建一个Tomcat实例并将程序部署上去。这就是我们所想要的。
调整应用
为了能生成用来分析的hotspot.log文件,我们得给我们这个示例程序的进程增加几个JVM选项。
这是JITWatch的
WIKI页面上推荐的选项:
[*]XX:+UnlockDiagnosticVMOptions -XX:+TraceClassLoading -XX:+LogCompilation -XX:+PrintAssembly
把这些选项添加到Tomcat进程中最简单的方法就是直接增加到maven里面。执行一下 :
export "MAVEN_OPTS=$MAVEN_OPTS -XX:+UnlockDiagnosticVMOptions -XX:+TraceClassLoading -XX:+LogCompilation -XX:+PrintAssembly"
如果你的JDK警告说“PrintAssembly is disabled”,去下载一个hsdis就好了([url=http://dropzone.nfshost.com/hsdis.htm” target=“_blank”>WINDOWS[/url], <a href=]Linux[/url], <a href="http://www.nitschinger.at/Printing-JVM-generated-Assembler-on-Mac-OS-X” target=“_blank”>OSX[/url])。
准备就绪,出发!
只需一个mvn tomcat:run命令,我们就能看到一个hostpot_pid${pid}.log的文件,这里${pid}是JVM进程的ID,文件在petclinic工程的父目录中。
点击Config按钮将源码及类文件的路径关联起来,这样你的体验会更好一些。Add JDK src按钮会自动地将JDK源码的路径加上,因此你就点击一下就好了。
现在开始分析吧,过一会儿JITWatch就会出结果了。
一些额外的特性
从JITWatch所提供的信息你能了解到什么?首先,会有一张编译的时间轴图。看到它我知道得等个一分钟左右才能编译完基本的类:注意,我们并没有给应用添加任何负载,因此我们定义的那些类还没有开始编译。
还有一个有用的东西就是最大字节码方法排行榜。方法越小,它就越有可能被JIT编译器内联。因此大的方法不只是降低了可读性,它还会带来性能的消耗。从这个视图可以看到哪些类或者方法是需要拆分的。
当然还有TriView,通过它你能看出机器目前究竟在执行什么东西。下面是TriView的一个示例,它显示的是一个BigInteger(String, int)的构造方法正在执行的过程,三个窗口还会同步高亮显示。
如果你感兴趣的方法还没有编译,JITWatch会提醒你,你可以给你的应用增加一些负载,或者调低一下JIT的阈值,这样编译器会认为这个方法执行的足够频繁,就会将它进行编译。
结束语:使用JITWatch来更好地查看应用的性能,负载以及执行速度
我们已经简单地了解了JVM的JIT是如何将字节码编译成机器代码的了,并创建了一个示例工程来进行实验。事实上,JITWatch就是一个非常简单直接的工具,你能够直观地了解到你的Java程序正在发生些什么。
如果你希望能更流畅地阅读JVM的字节码,我推荐你看一下我们的JRebel产品的老大写的
这篇文章。
原创文章转载请注明出处:
http://it.deepinmind.com
英文原文链接
分享到:
相关推荐
JITWatch用户界面是使用JavaFX构建的。 这包含在Oracle JDK中。 如果您使用的JDK不包含JavaFX(例如Azul Zulu或Linux上的某种打包的OpenJDK),则可以从下载预构建的OpenJFX jar,并将其放入构建类路径中。 蚂蚁 ...
在Mac环境下,使用JITWatch来查看JDK 1.8的汇编代码是一个非常有用的技巧,这有助于我们深入理解Java程序的运行机制,特别是JIT(Just-In-Time)编译器的工作原理。JITWatch是一款由Adrian Lamothe开发的可视化工具...
完成编译后,生成的JITWatch应用可以与JDK配合使用,进行JIT编译器行为的分析。 最后,`hsdis-win-amd64.zip`提供了HotSpot服务代理(hsdis),这是一个动态字节码反汇编器,对于理解JIT编译后的机器码至关重要。它...
攻击者可能会使用一些开源的JIT库,如.NET的DynamicMethod或JavaScript的V8引擎,来生成和执行代码。 - `advanced_shellcode`:这个名字暗示了一个更为高级的shellcode实现,可能涉及到更复杂的内存操作、混淆技巧...
Log analyser and visualiser for the HotSpot JIT compiler. Video introduction to JITWatch video Slides from my LJC lightning talk on JITWatch slides For instructions and screenshots see the wiki ...
在这个场景中,“matlab开发-效率Kneast使用jit搜索邻居”涉及到的是如何在MATLAB中优化KNN搜索过程,以提高计算效率。 KNN搜索通常包括两个主要步骤:距离计算和最近邻查找。在MATLAB中,这两个步骤都可能成为性能...
使用Trace-Based JIT,编译器可以跨方法边界跟踪并优化整个执行流程中的关键路径,而不是仅仅优化单个方法。 #### Trace-JIT架构 Trace-JIT架构主要由以下几个组成部分构成: 1. **Trace识别**:通过运行时分析...
JavaScript引擎如V8(Chrome和Node.js使用)、SpiderMonkey(Firefox使用)以及JSC(Safari使用)都实现了JIT技术。这些引擎在执行JavaScript时,会根据不同的策略选择何时进行编译。例如,V8采用了分层的JIT编译...
此外,还可能涉及到开源工具或库的使用,比如开源的JIT编译器实现,以及用于网络拓扑图可视化的开源库。 总之,"JIT实现拓扑展现"是一个融合了程序性能优化和图形化信息展示的技术话题。理解JIT的工作原理和应用,...
- **电源管理**:监控并控制系统的电源状态。 - **传感器管理**:处理来自硬件传感器的数据。 - **USB管理**:处理USB连接相关的事件。 - **键盘管理**:管理键盘输入事件。 通过上述组件和服务,开发者可以轻松...
例如,在某生产线中采用进度条的形式监控每条生产线的每个工序状态,一旦某个工序完成,进度条相应更新,同时通过看板通知下一工序准备生产。这种方式使得整个生产过程更加透明化,有助于快速识别瓶颈环节并采取措施...
在虚拟机启动时,会同时启动JIT线程,这个线程负责监控代码的执行频率。当一段代码被频繁调用时,JIT线程会将其标记为需要编译的目标,然后将其转换为机器码。这些编译后的代码会被存储在entry table中,以便后续...
这两种技术充分利用了浏览器内广泛使用的高级脚本解释器或虚拟机的攻击面。 #### 关键技术介绍 ##### 指针推断(Pointer Inference) 指针推断是一种技术,它用于在存在ASLR的情况下确定内存中shellcode字符串的...
决定使用哪种JIT编译器的因素包括操作系统、应用程序需求和内存限制。32位JVM在内存使用效率和启动速度上有优势,而64位JVM则更适合处理大内存和高计算密集型任务。在选择JVM版本时,需要根据具体操作系统来指定32位...
精益生产是一种旨在消除浪费、提高效率的生产管理理念,它起源于日本丰田公司的JIT(Just In Time)生产方式。JIT的核心理念是按照实际需求,适时、适量地生产产品,以达到零库存、减少浪费的目标。传统的批量生产...
“Writing JIT-Spray Shellcode for fun and profit”这一主题深入探讨了如何利用Just-In-Time(JIT)编译器的特性来实施攻击,尤其关注绕过现代浏览器如Internet Explorer 8及其后续版本中的防御机制。以下是对该...
jvm初识及JIT优化jvm初识及JIT优化jvm初识及JIT优化jvm初识及JIT优化jvm初识及JIT优化jvm初识及JIT优化jvm初识及JIT优化jvm初识及JIT优化jvm初识及JIT优化jvm初识及JIT优化jvm初识及JIT优化jvm初识及JIT优化jvm初识...
CLR使用类型的方法表来路由所有的方法调用。类型的方法表由多个入口项组成。每个入口项指向一个唯一的存根例程。初始化时,每个存根例程包含一个对于CLR的JIT编译器的调用。在JIT编译器生成本机代码 后,它会重写...