JProfiler简介
时间:2010-08-25 来源:汤汤的随笔
JProfiler 是一个著名的用于 java 系统监控分析的软件,功能很强大,可以监控普通的 java application, applet, java web start, application server 等等。除了可以监控本地的程序,还可以对远程服务器上跑的应用进行监控。
其中的allocation call tree,能够发现哪个函数占用了最大的内存,最后就能定位到发生泄漏或者内存使用过大的地方进行优化了。譬如一个方法就占用了大量的CPU和内存这种是很有问题的。
JProfiler的官方网站http://www.ej-technologies.com/download/overview.html
下面引用一个朋友的例子:http://benben.javaeye.com/blog/312416
最近用JProfile测试一个比较大的工程,希望能找到一些程序运行的瓶颈。过去使用Hibernate,很多人反映效率低。特别是懒加载关闭的时候,对象的持续生成最后会导致JVM直接OutOfMemory错误。目前使用iBatis,发现临时对象还是特别多,一开始百思不解。通过使用JProfile以后,终于找到了原因所在。
对象引用关系:baseView ->InstanceModel -> City
其中,baseView 引用了InstanceMode,而InstanceMode 引用了City对象,City对象是一个比较简单的对象,只有id、name、中文名称等属性。在工程实际使用环境中,InstanceModel 是比较多的,可能会有数万经常被使用。通过对JVM堆的观察,发现每次InstanceModel对象生成的时候,都会附带出大量的City对象。由于一般应用中City的个数都有限,所以程序中专门对City对象作了缓存。为什么会产生大量City的临时对象呢?
通过在JProfile中查看堆的情况,可以很清楚的看到上述引用关系。这很正常啊?纳闷中,反复查看堆、对象、引用关系等信息,终于发现了线索。那就是,被引用的City对象中只有ID值,没有中文名称等其他信息。这就让我们找到了突破口,通过与开发工程师的交谈,被告知只使用了ID值,没有使用其他的属性。于是我们找到iBatis加载baseView对象的映射文件:
<resultMap id="baseView" class="View">
…
<result column="CITYCODE"
property="InstanceModel.city.id" jdbcType="NUMERIC" />
</resultMap>
注意,在上面这个定义文件中,加载View对象的时候,从同一张数据库表中,加载了View所属的City的代码(id)。但是iBatis框架在达到这个目的的同时,生成了一个临时City对象,并把ID赋了值。这就是原因!!
好了,原因找到了,优化的方案自然就出来了。只需要去掉InstanceModel对City对象的引用,直接取City的ID就行了!再次运行JProfile,发现不再生成大量的City临时对象,优化的目的达到了。
结论:使用Hibernate、iBatis等框架的时候,我们过于热衷于对象引用的方便,忽视了这种方便的代价。有时候,我们只为了使用一个简单类型的数据,却大量加载肥胖对象而不自知。然后抱怨框架效率低,有问题。其实回头看看,良好的数据库设计、良好的对象设计这些基本的东西,是任何框架都不能帮我们做的。同时感叹JProfile这种强大工具给我们带来的好处,让我感觉又回到了DOS Debug 的时代。
JProfiler也可以远程监控,在windows监控远程的linux的情况,不过必须在两台机器上都装有jprofiler才可以。
JProfiler也可以远程监控,在windows监控远程的linux的情况,不过必须在两台机器上都装有jprofiler才可以。
相关阅读 更多 +