JAVA性能调优

Posted BYITTD

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA性能调优相关的知识,希望对你有一定的参考价值。

JAVA性能调优



前言



1.程序的性能如何表现


执行速度:程序的反应是否迅速,响应是否足够短


内存分配:内存分配是否合理,是否过多消耗内存,或者存在泄露。


负载承受能力:当系统压力上升时,系统的执行速度、响应时间的上升曲线是否平缓。


2.性能的参考指标


执行时间、CPU时间、内存分配、磁盘吞吐量、网络吞吐量、响应时间


3.性能瓶颈


磁盘IO、网络操作、CPU、异常、数据库、锁竞争、内存


性能调优的层次



1.设计调优


设计调优处于所有调优手段的上层,它往往需要在软件开发前进行。在软件开发之初,软件架构师就应该评估系统可能存在的各种潜在的问题,并给出合理的设计方案。设计调优对性能的影响也是最大的。如果说代码优化、JVM调优是对系统微观层面上“量”的优化,那么设计优化就是对系统在宏观层面上“质”的优化。


2.代码调优


3.JVM调优


java程序运行在JVM上的,对JVM优化能在一定程度上提升JAVA程序的性能。例如内存和GC的优化。


4.数据库调优


SQL优化。数据库配置优化。


================================

优化步骤


1.需要明确性能目标;

2.系统性能测试;

3.定位性能瓶颈;

4.定位代码;

5.分析问题,提供解决方案.

================================


设计优化



1.单例模式


1.饿汉式(直接初始化好,不能实现延迟加载); 

2.懒汉式(要加同步代码块); 

3.静态内部类(实现延迟加载)(类加载的时候,内部类没有创建)


2.代理模式


用于实现延迟加载;远程调用的网络代理;安全因素的安全代理;

hibernate框架,使用动态代理模式。CGLIB.jar

spring AOP 动态代理


3.享元模式


提高系统性能为目的的模式之一,避免对象的重复创建,提高数据的重用性,空间换时间的做法。

例子:获取员工信息。先从缓存中查找,没有,去数据库查询,然后放入到缓存。


4.装饰者模式


这是一个设计非常巧妙的结构,它可以动态添加对象的功能。在基本的设计原则中,有一条重要的设计准则:合成/聚合复用原则。根据该原则的思想,代码复用应该尽可能使用委托,而不是使用继承。应为继承是一种紧密的耦合,任何父类的改动都会影响其子类。而委托则是松耦合,只要接口不变,委托类的改动并不会影响其上层对象.装饰者模式就充分运用了这种思想,用过委托机制,复用系统中的各个组件,在运行时,可以将这些功能自检进行叠加,使其拥有所有组件的功能.而各个子功能模块,被很好的维护在各个组件的相关类中,拥有整洁的系统结构.jdk中 I/O流 OutputStream InputStream。通过装饰者增加功能,BufferedOutputStream


5.观察者模式


观察者Observer,被观察者Observable避免轮询监听状态。状态修改时,主动通知常用的优化组件和方法缓冲 buffer缓存对象池数据库连接池并行替换串行负载均衡 Neginx 反向代理时间换空间 (CPU运行节约内存)空间换时间 (缓存)


java代码优化



1.慎用异常


异常捕获,放在循环外面


2.使用局部变量


调用方法时传递的参数以及在调用中创建的临时变量都保存在栈(stack)中,速度较快。其他变量,入静态变量、实例变量等,都在堆(heap)中创建,速度较慢。


3.一维数组替换二维数组


4.提取运算表达式


5.静态方法,替换实例方法


常用工具类方法,使用静态方法。因为在java中,由于实例方法需要维护一张类似虚拟函数表的结构,以实现多动态支持。与静态方法相比,实例方法调用需要更多的资源。


jvm调优



java虚拟机的内存模型:程序计数器;虚拟机栈;本地方法栈;java堆;方法区(永久区)


1.程序计数器


程序计数器(program counter register)是一块很小的内存空间。由于java是支持多线程的语言,当线程数量超过CPU数量时,线程之间根据时间片轮询抢夺CPU资源。为此,每一个线程都必须用一个独立的程序计数器,用来记录下一条要运行的指令。各个线程之间的计数器互补影响,独立工作;是一块私有的内存空间。


2.java虚拟机栈


java虚拟机栈也是线程私有的内存空间,它和java线程在同一时间创建,用来保存方法的局部变量、部分结果,并参与方法的调用和返回。



3.本地方法栈


和java虚拟机栈的功能很相似,java虚拟机栈用于管理java函数的调用,而本地方法栈用于管理本地方法的调用。本地方法并不是java实现的。在SUN的hot spot 虚拟机中,不区分本地方法栈和虚拟机栈。


4.java堆 heap


java堆是java运行时内存中最为重要的部分,几乎所有的对象和数组都是在堆中分配的。java堆分为新生代和老年代,新生代用于存放刚刚产生的对象和年轻的对象,如果对象一直没有被回收,生存的足够长,老年对象就会被移入老年代。新生对象有可进一步细分为eden / survivor space0 / survivor space1。Eden意思是伊甸园,即对象的出身地,大部分对象刚刚建立时,通常会存放在这里。s0和s1为survivor空间,直译为幸存者,也就是说存放其中的对象至少经历了一次垃圾回收,并得以幸存。如果在幸存区的对象到了指定年龄扔未被回收,则有机会进入老年代(tenured)


5.方法区


方法区也是jvm内存区非常重要的一块内存区域,与堆空间类似,它也是被jvm中所有线程共享的。方法区主要保存的信息是类的元数据。方法区中最为重要的是类的类型信息、常量池、域信息、方法信息。类型信息包括类的完整名称、父类的完整名称、类型修饰符和

类型的直接接口类表;常量池包括这个类方法、域等信息所引用的常量信息;域信息包括域名称、域类型和域修饰符;方法信息包括方法名称、返回类型、方法参数、方法修饰符、方法字节码、操作数栈和方法帧栈的局部变量区大小以及异常表。总之方法区保存的信息,大部分来自于class文件,是java应用程序运行必不可少的重要数据。在hot spot 中 方法去也称为永久区,是一块独立于java堆的内存空间。虽然叫做永久区,但是在永久区中的对象,同样也是可以被GC回收的。一是GC对永久常量池的回收(常量池的常量没有被应用,String.intern()方法加入常量池);二是永久区对类元数据的回收(动态代理创建对象)。


参数设置



-Xms128M  设置最小堆内存


jvm会试图将系统内存尽可能的限制在-Xms中。当内存实际使用量触及-Xms时,会出发Full GC。将-Xms和-Xmx设置相同,可减少GC次数。


-Xmx256M  设置最大堆内存


-Xmn256M  设置新生代


设置为整理堆空间的1/4到 1/3左右。设置一个较大的新生代会减小老年代的大小,这样系统性能和GC很大影响。

设置-Xmn等同于设置了相同的-XX:NewSize=256M和-XX:MaxNewSize=256M


-XX:PermSize=128M


初始持久代大小


-XX:MaxPermSize=128M


持久代最大值

持久代的大小直接觉得了系统可以支持多少了类定义和多少常量。一般设置为64M,建议不超过128M



-Xss1M  线程栈(表示每个线程拥有1MB的栈空间)


设置过大,则系统所能运行的线程数会下降


-XX:SurvivorRatio=2


设置新生代比例关系


-XX:SurvivorRatio=eden/s0=eden/s1


-XX:NewRatio=2


设置老年代和新生代的比例


-XX:NewRatio=老年代/新生代



总结



JVM调优的主要过程有:确定堆内存大小(-Xms、-Xmx);合理分配新生代和老年代(-XX:NewRatio、-Xmn、-XX:SurvivorRatatio);确定永久区大小(-XX:PermSize、-XX:MaxPermSize)、选择垃圾收集器、对垃圾收集器合理设置。禁用显示GC(-XX:+DisableExplicitGC),禁用类元数据回收(-Xnoclassgc),禁用类验证(-Xverify:none)等设置,来提升系统性能。





温馨提示

文章来源与网络,如有异议,请联系我删除!

         





以上是关于JAVA性能调优的主要内容,如果未能解决你的问题,请参考以下文章

Day776.如何制定性能调优策略 -Java 性能调优实战

Java:如何更优雅的性能调优?

面试必备:深入 Java 应用性能调优实践

Tomcat 性能调优

性能测试系列-java gc调优

JAVA性能调优