加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

Java应用程序性能调优技术

发布时间:2020-12-12 03:02:29 所属栏目:MySql教程 来源:网络整理
导读:《Java应用程序性能调优技术》要点: 本文介绍了Java应用程序性能调优技术,希望对您有用。如果有疑问,可以联系我们。 Java应用程序,不管他们部署到的应用程序服务器,往往会遇到同样的问题集.作为Java EE调谐器,我已经裸露于各种环境,并对常见问题提出了一

《Java应用程序性能调优技术》要点:
本文介绍了Java应用程序性能调优技术,希望对您有用。如果有疑问,可以联系我们。

Java应用程序,不管他们部署到的应用程序服务器,往往会遇到同样的问题集.作为Java EE调谐器,我已经裸露于各种环境,并对常见问题提出了一些意见.在这方面,我看到我的角色与汽车修理师的角色相似:你告诉你的技工,引擎是啁啾的; 那么他会问你一系列问题,指导你量化啁啾的性质,位置和情况.从这些信息中,他形成了一个关于问题的一些可能原因的好主意.

我会分享我在现场遇到的一些常见问题及其症状.这些步调将使我们能够使代码运行顺利并避免性能问题.

1)使用StringBuilder

这应该是几乎所有Java代码中的默认值.尽量避免+运算符.当然,你可能会认为这只是StringBuilder的语法糖,如下所示:

String x = “a” + args.length + “b” ;

...编译

0 新 的java .lang .StringBuilder [16]3 DUP4 LDC < 字符串 “ 一 ”> [18]6 invokespecial 的java .lang .StringBuilder(java的.lang .String)[20]9 aload_0 [参数] 10 arraylength 11 invokevirtual 的java .lang .StringBuilder .append(INT):的java .lang .StringBuilder [23] 14 LDC < 字符串 “ b ”> [27] 16 invokevirtual 的java .lang .StringBuilder .append(java的.lang .String):java的.lang . StringBuilder的 [29] 19 invokevirtual 的java .lang .StringBuilder 的ToString():的java .lang .String [32] 22 astore_1 [X]

但是,如果以后,您必要使用可选部分修改您的String?

String x = “a” + args.length + “b” ; if(args.length == 1)x = x + args [ 0 ];

现在你将有一秒钟 StringBuilder,只是不需要地消耗你的堆的记忆,给你的GC施加压力.写这个:

StringBuilder x = newStringBuilder(“a”);X.append(args.length);X.append(“b”);if(args.length == 1);X.append(args [ 0 ]);

在上面的例子中,如果你使用了显式的StringBuilder实例,或者你依靠Java编译器为你创立隐式实例,这可能是完全不相干的.但请记住,我们在NOPE分行.每个CPU周期,我们都浪费在像GC那样愚蠢的东西,或者分配一个StringBuilder的默认容量,我们浪费了N x O x P次.

根据经验,总是使用StringBuilder而不是+运算符.如果可以,请保持StringBuilder引用跨多个办法,如果您的String更复杂的构建.

为了大声哭泣,如果还有StringBuffer引用,请用StringBuilder替换它们.你真的几乎不必要在正在创建的字符串上进行同步.

2)内存不敷错误

困扰企业应用程序的最常见问题之一是可怕的OutOfMemoryError.差错通常是以下之一:

  • 应用程序服务器瓦解.

  • 性能下降.

  • 一个似乎无休止的重复垃圾回收循环几乎停止处理,通常会导致应用程序服务器瓦解.

无论症状如何,在性能恢复正常之前,您很可能必要重新启动应用程序服务器.

内存不敷错误的原因

在尝试办理内存不足错误之前,首先了解如何发生错误是有益的.如果JVM在其进程内存空间(包括堆中的所有区域)以及永久内存空间中的内存不足,并且进程尝试创建新的对象实例,则会执行垃圾回收器以尝试释放足够的内存允许新对象的创建.如果垃圾收集器无法释放足够的内存来容纳新对象,那么它会抛出一个OutOfMemoryError.

内存不足错误最常见于Java内存泄漏.从以前的讨论中回顾一下,Java内存泄漏是维护对未使用对象的延续引用的结果:您完成了使用对象,但是由于一个或多个其他对象仍然引用该对象,因此垃圾收集器无法回收其内存.因此,该对象所占用的内存从可用堆中丢失.这些类型的内存泄漏通常发生在Web哀求期间,而一个或两个泄露的对象可能不会使应用程序服务器崩溃,10,000或20,000个哀求可能会发生.此外,泄漏的大多数对象不是简单的对象,如整数或双精度,而是代表堆内的子图.例如,您可能会无意中持有Person对象,并且该Person对象具有一个Profile对象,该对象具有多个PerformanceReview对象,每个对象都维护数据集.而不是丢失Person对象占用的100个字节的内存,您将丢失可能占用500 KB或更多内存的整个子图.

为了识别此问题的根源,您必要确定是否存在真实的内存泄漏,或者是否将其他内容显示为OutOfMemoryError.

做出这样的决准时,我使用以下两种技巧:

  • 阐发深度内存统计信息.

  • 反省堆的增长模式.

所有JVM(如Sun和IBM)的JVM调优过程都不相同,但存在一些配合点.

3)避免正则表达式

正则表达式比拟便宜便宜.但是,如果您在NOPE分支机构,那么他们是最糟糕的事情.如果绝对必须在计算密集型代码段中使用正则表达式,至少缓存“模式”引用,而不是重新编译它们:

staticFinalPattern HEAVY_REGEX = Pattern.compile(“(((X)* Y)* Z)*”);

然则如果你的正则表达式真的很傻,就像

String [] parts = ipAddress.split(“”);

那么你真的更好地采用普通 char[] 或基于索引的把持.例如,这个完全不可读的循环也是一样的:

intlength = ipAddress.length();toffset = 0 ;intpart = 0 ;for(inti = 0 ; i < length ; i ++){if(i == length - 1 || ipAddress.charAt(i + 1)== '.'){ parts [part] = ipAddress.substring(offset,i + 1); 部分+ +; offset = i + 2 ;}}

...这也显示了为什么你不应该做任何过早的优化.与split() 版原形比,这是不可维护的.

4)不要使用iterator()

现在,这个建议真的不是一般用例,而只适用于NOPE分支.不过,你应该考虑一下.编写Java-5风格的foreach循环很便利.你可以完全忘记循环的内部,并写道:

对于(String value:strings){//在这里做一些有用的事情}

但是,每次遇到这个循环时,如果字符串是一个Iterable,您将创立一个新的Iterator实例.如果您使用的是ArrayList,那么将在堆上分配一个3个int的对象:

privateClassItr implementsIterator < E > { intcursor;

相反,您可以编写以下等效循环和“浪费” int 堆栈上的单个 值,这是很廉价的:

intsize = strings.size();for(inti = 0 ; i < size ; i ++){字符串值:strings.get(i); //在这里做一些有用的事情

...或者,如果您的列表没有真正转变,您甚至可以在其阵列版本上操作:

对于(String value:stringArray){//在这里做一些有用的事情}

5.使用原语和客栈

上面的例子来自jOOQ,它使用了很多泛型,因此被强制使用包装类型为byte,short,int和long,至少在Java 10和项目Valhalla中可以使用泛型之前.但你可能没有这个约束在您的代码,所以你应该采取一切步伐替换:

//去堆 整数i = 817598 ;

… 有了这个:

//在堆栈上保存inti = 817598 ;

使用数组时,事情会变得更糟.替换为:

//三堆工具!整数[] I = { 1337,424242 };

… 有了这个:

//一个堆对象.INT [] I = { 1337,424242};

当您深入您的NOPE分支时,您应该非常警惕使用包装类型.有可能你会在你的GC上造成很大的压力,因为它必需一直踢在一起清理你的混乱.

一个特别有用的优化可能是使用一些原始类型并创立它的大的一维数组,以及一些分隔符变量来指示编码对象在数组上的位置.

一个优秀的原始集合库,比您的平均int []更繁杂一点,它是与LGPL一起使用的trove4j.

这个规矩有一个例外:布尔值和字节有足够的值被JDK完全缓存.你可以写:

Boolean a1 = true ; // ...语法糖为:Boolean a2 = Boolean .valueOf(true);字节 b1 =(字节)123 ; // ...语法糖为:字节 b2 = 字节 .valueOf((字节)123);

其他整数基元类型的低值也同样如此,包含char,int和long.但是,只有当你自动打包它们,或者调用TheType.valueOf()时,不是当你调用构造函数时!

结论

为了有效地诊断性能问题,您需要了解问题症状如何映射底层问题的根本原因.如果您可以将问题分解到应用程序代码,那么您需要将问题转发给应用程序支持代理,但如果问题出在环境中,则办理问题是在您的控制之内.

问题的根源在很大程度上取决于许多因素,但是一些指标可以在诊断问题和完全消除其他问题时增加信心.我希望本文可以作为您的Java环境的开始故障排除指南,您可以随着问题呈现,自定义您的环境.

大家可以点击参加群:606187239【JAVA大牛学习交流】

里面有Java高级大牛直播讲解知识点 走的便是高端路线

(如果你想跳槽换工作 然则技术又不够 或者工作上遇到了

瓶颈 我这里有一个JAVA的免费直播课程 讲的是高端的知识点

基础欠好的误入哟 只要你有1-5年的开发经验

可以加群找我要讲堂链接 注意:是免费的 没有开发经验误入哦)

编程之家PHP培训学院每天发布《Java应用程序性能调优技术》等实战技能,PHP、MYSQL、LINUX、APP、JS,CSS全面培养人才。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读