论坛首页 Java企业应用论坛

三种常见的Java应用性能挑战

浏览 12570 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (1) :: 隐藏帖 (16)
作者 正文
   发表时间:2010-12-25   最后修改:2010-12-25
Java是一种伟大的语言。它管理内存,传授面向对象的编程(思想),使我们更好地用它来编码。另外,它确实是一种“编写一次,到处运行“的语言。然而,Java应用程会遇到一些常见的开发者和应用者独耳熟能详的性能挑战。

内存泄露

Java的最大的好处之一是它能够管理内存模型。当对象不再使用时,Java会做清理工作。较旧的语言需要人工来管理内存,但开发者宁愿花时间专注于核心语言逻辑而不愿为内存分配而忧心。

话虽如此,却不能保证Java的内存管理没有问题,提供管理内存模型,或创建/销毁未使用的对象,(这些对象)都放在Java的“堆(Heap)“中,内存泄露通常是不正确编程的结果–通常,开发者没有消除某一对象的所有引用,因此,堆(空间)逐步耗尽,应用程序也将死机。

大多数人使用堆转储和/或事件探查器(profiler)来诊断内存泄漏。堆转储使你可看到哪个对象持有对集合的引用。它告诉你集合何处,但不能告诉你谁在存取该集合或其它能让你探究根源的特性。堆转储通常占用的空间也相当大,在千兆字节,分析并打开一个堆转储需要大量资源,然后读取它,并找出问题所在。

第二种方法,是组合堆转储和事件探查器,使你能接近点问题本质,但并不多。内存分析器尽力帮助您分析您的堆转储。他们有实时数据,现在可知道是谁创建的对象,但仍不知造成泄漏的真正根由。

堆转储和分析器都有益于开发和预生产,然而,一旦应用程序失控,分析器也不可用。隔离并解决内存泄漏最有效的方法来之一是通过事务(transaction)(管理)和代码路径分析。通过采取事务快照,可以获得问题所在及其原因,这通常会导致更少的停机时间和更好的MTTR。

缓慢的SQL

几乎每一应用程序都会使用JDBC数据库。应用中一个非常普遍的问题是糟糕的SQL的性能,这可有时由于字段未创建索引、获取的数据量太多或者其他原因所致。这会不利于应用的性能,因为大多数应用程序在每一应用请求中涉及很多SQL调用。

可能有很多造成SQL执行缓慢的原因,但是其中之一特别突出:对象-关系映射(ORM)。

ORM以成为将当今两大业务应用基础技术(面向对象的应用(Java,.NET)和关系数据库(Oracle、MySQL和PostgreSQL等))整合在一起的首选方法。今天的大多数应用采用关系数据库,对于许多开发人员而言,(ORM)这项技术可以消除需要升入探讨着两种技术如何相互作用的复杂度。然而,ORM使得应用需承受额外的负担,并极大地影响应用的性能,而一切表面上看起来很好。

在大多数情况下,检索数据所消耗的时间和占用资源的数量级远大于数据处理所需的时间及资源,因此,性能方面的考虑常包含访问和存储数据的工具和方法就不足为奇了。

虽然开发人员直观地使用(隐藏复杂性),但ORM在应用性能方面应占据很大的比重,以确保(开发人员)明白问题的实质。

线程/同步

由同步所产生的问题往往很难辨认,但是其对性能的影响却非常显著。

对同步的最根本的需要在于Java对并发的支持,这通过在相同的过程中执行不同的线程(thread)代码来实现。单独的线程之间可以共享相同的资源,以及内存中的对象。虽然是一种完成更多工作的有效方法(当以线程在等待I/O操作完成期间,另一线程可利用CPU来进行计算),但是也曝露出应用的干扰和一致性问题。

为防止这种情况,程序员在程序中引入“synchronized”关键字来强制并发线程的执行顺序。利用“synchronized”来防止线程在同一时间获得同一资源,并防止数据不一致。

然而在实践中,这个简单的机制却带来很大的副作用。现代企业的应用常采用多线程的实现模式,同时执行多个线程,对“共享”对象的争夺也随之加剧,同步将有效地强制并发处理转而为顺序执行。

目前,对于线程和同步问题没有银弹(silver bullet)。某些开发者依赖“防御”性编程方法,诸如加锁;而另一些开发者,则依赖STM(Software Transactional Memory Systems)来缓解这个问题。最好的开发组织是那些可以平衡代码审查/重写负担和性能问题的团队。

这些只是Java开发人员每天必须面对的应用性能问题,有许多有用的性能工作可以大大减少此类问题。

原文地址: http://simpleframework.net/simple/news/v.jsp?__news_beanId=0457345649_01078129255&__news_Id=3945
   发表时间:2010-12-25  
java需要性能吗?那要C++干什么。。
0 请登录后投票
   发表时间:2010-12-25  
分析算法,sql,线程,socket

这个才是关键。
crud一般不需要关心性能。

真有性能问题的话,lz的文章p用都没有。
0 请登录后投票
   发表时间:2010-12-25  
java 只要没有OOM,其他都是数据库的调优了,然后再加个cache, 一般1000W级别访问量,这样就能满足了,企业级应用也就这样了
0 请登录后投票
   发表时间:2010-12-25  
不要性能,taobao的都是在吃屎吗?
0 请登录后投票
   发表时间:2010-12-26   最后修改:2010-12-26
java应用,尤其是web 应用关注性能 那是必须的。诸如taobao 每天访问量那么大,没有即时响应还玩什么。 

搂主的文章涉及了性能,但大概这些还不太全面。

性能,哪里都有可能是瓶颈,有可能是带宽,有可能是访问sql(如果牵扯到读库的话),有可能是前台页面渲染,如果读取内容过多的话,也有可能是对临界资源的竞争,也有可能是本身算法设计上的欠缺。 这些都是需要跟踪调优的。而搂主这篇涉及有些浅有些泛,也不太全面,比如 多线程那里,就有很多优化方式,比如针对不同的机器(CPU数)决定并发线程数,利用这种方式来减少资源竞争,减少线程上下文切换。再比如,针对数据内容过多,可以采用异步加载,缓存,甚至数据分离(不同业务数据放置在不同的server上,这样可以并发读取),然后在读取的时候采用诸如分页思想限制取的数据多少来进行,至于前台展示后,可以采用异步加载ajax请求,或者是简单的json方式来处理后续的数据请求了。至于内存方面,OOM只能说是一个设计问题,优化的时候 解决的应该是gc过于频繁导致其他线程频繁被挂起的行为,这种的话,大致是控制业务数据量(很多在设计的时候都不太注意这点), 监控大数据的应用,尽力减少这些使用的内存量才是王道,实在不行,那就硬件扩增了,比如32到64位,内存容量必然可以加大了,这样的动态扩容要求的是你的jvm配置最好按照所占内存的比例来配置了。至于sql优化,一般看下读写比例,合理利用索引了,然后就是注意每次请求取到的数据数量(分页),至于一些批处理操作,如果任务独立的话,可以适当的利用多线程并发处理了(并发是“七伤拳”),一定要多自测,保证并发是提高了性能哈。

性能问题还有很多很多,受限于经验,我先扯这么点吧 ,抛砖引玉,欢迎老鸟更详细的介绍。 性能优化,每一个coder的必修课。 理论派到此一游 ,哈哈
0 请登录后投票
   发表时间:2010-12-26  
苍山洱海 写道
java需要性能吗?那要C++干什么。。



china需要民主吗?那要USA干什么。。
0 请登录后投票
   发表时间:2010-12-26  
性能的调优是看业务的需求的, 你只有10W,100W的访问量,调个毛啊, 有这个时间还不如看看业务的需求改进。 当你业务量大的时候,调优才能看到明显的效果, 调优基本上是在,空间换时间,
0 请登录后投票
   发表时间:2010-12-26  
内存泄露、线程/同步、缓慢的sql,恐怕不仅仅是java的瓶颈,其他编程语言也基本都存在这些问题。
要优化,从硬件下手,还好说;从code下手,如果不是原来代码写的太烂的话,个人经验,代码的可读性必然会变差。如果文档赶不上,估计维护是个大问题。
0 请登录后投票
   发表时间:2010-12-27  
我看批评的声音很大,但LZ写出来也不易,看看也无妨
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics