`
linkyou66
  • 浏览: 228092 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

JProfile调优经验(很正确)

 
阅读更多
<div>最近用JProfile测试一个比较大的工程,希望能找到一些程序运行的瓶颈。过去使用Hibernate,很多人反映效率低。特别是懒加载关闭的时候,对象的持续生成最后会导致JVM直接OutOfMemory错误。目前使用iBatis,发现临时对象还是特别多,一开始百思不解。通过使用JProfile以后,终于找到了原因所在。</div>
<div></div>
<div>对象引用关系:baseView -&gt;InstanceModel -&gt; City</div>
<div>其中,baseView 引用了InstanceMode,而InstanceMode 引用了City对象,City对象是一个比较简单的对象,只有id、name、中文名称等属性。在工程实际使用环境中,InstanceModel 是比较多的,可能会有数万经常被使用。通过对JVM堆的观察,发现每次InstanceModel对象生成的时候,都会附带出大量的City对象。由于一般应用中City的个数都有限,所以程序中专门对City对象作了缓存。为什么会产生大量City的临时对象呢?</div>
<div>通过在JProfile中查看堆的情况,可以很清楚的看到上述引用关系。这很正常啊?纳闷中,反复查看堆、对象、引用关系等信息,终于发现了线索。那就是,被引用的City对象中只有ID值,没有中文名称等其他信息。这就让我们找到了突破口,通过与开发工程师的交谈,被告知只使用了ID值,没有使用其他的属性。于是我们找到iBatis加载baseView对象的映射文件:</div>
<div><span style="font-size: 10pt;"> <span style="color: #a65700;">&lt;</span><span style="color: #5f5035;">resultMap</span> <span style="color: #274796;">id</span><span style="color: #808030;">=</span><span style="color: #0000e6;">"baseView"</span> <span style="color: #274796;">class</span><span style="color: #808030;">=</span><span style="color: #0000e6;">"View"</span><span style="color: #a65700;">&gt;</span></span></div>
<div><span style="font-size: 10pt; color: #a65700;">    …</span></div>
<div><span style="font-size: 10pt;"> <span style="color: #a65700;">&lt;</span><span style="color: #5f5035;">result</span> <span style="color: #274796;">column</span><span style="color: #808030;">=</span><span style="color: #0000e6;">"CITYCODE"</span></span></div>
<div><span style="font-size: 10pt;"> <span style="color: #274796;">property</span><span style="color: #808030;">=</span><span style="color: #0000e6;">"InstanceModel.city.id"</span> <span style="color: #274796;">jdbcType</span><span style="color: #808030;">=</span><span style="color: #0000e6;">"NUMERIC"</span> <span style="color: #a65700;">  /&gt;</span></span></div>
<div><span style="font-size: 10pt;"> <span style="color: #a65700;">&lt;/</span><span style="color: #5f5035;">resultMap</span><span style="color: #a65700;">&gt;</span></span></div>
<div>注意,在上面这个定义文件中,加载View对象的时候,从同一张数据库表中,加载了View所属的City的代码(id)。但是iBatis框架在达到这个目的的同时,生成了一个临时City对象,并把ID赋了值。这就是原因!!</div>
<div>好了,原因找到了,优化的方案自然就出来了。只需要去掉InstanceModel对City对象的引用,直接取City的ID就行了!再次运行JProfile,发现不再生成大量的City临时对象,优化的目的达到了。</div>
<div></div>
<div>结论:使用Hibernate、iBatis等框架的时候,我们过于热衷于对象引用的方便,忽视了这种方便的代价。有时候,我们只为了使用一个简单类型的数据,却大量加载肥胖对象而不自知。然后抱怨框架效率低,有问题。其实回头看看,良好的数据库设计、良好的对象设计这些基本的东西,是任何框架都不能帮我们做的。同时感叹JProfile这种强大工具给我们带来的好处,让我感觉又回到了DOS Debug 的时代。</div>
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics