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

Java性能优化(转)

 
阅读更多

1、慎用异常

异常对性能不利。抛出异常首先要创建一个新的对象。Throwable接口的构造函数调用名为fillInStackTrace()的本地方法,fillInStackTrace()方法检查堆栈,收集调用跟踪信息。只要有异常被抛出,VM就必须调整调用堆栈,因为在处理过程中创建了一个新的对象。异常只能用于错误处理,不应该用来控制程序流程。

2、不要重复初始化变量

默认情况下,调用类的构造函数时,Java会把变量初始化成确定的值:所有的对象被设置成null,整数变量(byte、short、int、long)设置成0,float和double变量设置成0.0,逻辑值设置成false。当一个类从另一个类派生时,这一点尤其应该注意,因为用new关键词创建一个对象时,构造函数链中的所有构造函数都会被自动调用。

3、尽量指定类的final修饰符

带有final修饰符的类是不可派生的。在Java核心API中,有许多应用final的例子,例如java.lang.String。为String类指定final防止了人们覆盖length()方法。另外,如果指定一个类为final,则该类所有的方法都是final。Java编译器会寻找机会内联所有的final方法(这和具体的编译器实现有关)。此举能够使性能平均提高50%。

4、尽量使用局部变量

调用方法时传递的参数以及在调用中创建的临时变量都保存在栈中,速度较快。其他变量,如静态变量、实例变量等,都在堆中创建,速度较慢。另外,依赖于具体的编译器,局部变量还可能得到进一步优化。

5、使用移位操作代替乘法和除法

符号性质的乘除是一个很“昂贵”的操作,使用移位操作将会更快更有效

考虑下面的代码:

        for (val = 0; val<100000; val+=5)
        {
            alterX = val * 8;
            myResult = val * 2;
        }

用移位操作替代乘法操作可以极大地提高性能。下面是修改后的代码:

        for (val = 0; val <100000; val+= 5)
        {
            alterX = val <<3;
            myResult = val <<1;
        }

修改后的代码不再做乘以8的操作,而是改用等价的左移3位操作,每左移1位相当于乘以2。相应地,右移1位操作相当于除以2。值得一提的是,虽然移位操作速度快,但可能使代码比较难于理解,所以最好加上一些注释。
但是使用移位操作这个方法是一把双刃剑,除非是在一个非常大的循环内,性能非常重要,而且你很清楚你自己在做什么,使用这种方法比较合算。否则提高性能所带来的程序晚读性的降低将是不合算的。

6、避免在循环条件中使用复杂表达式

在不做编译优化的情况下,在循环中,循环条件会被反复计算,如果不使用复杂表达式,而使循环条件值不变的话,程序将会运行的更快。

复制代码
import java.util.Vector;
class CEL
{
    void method(Vector vector)
    {
        for (int i = 0; i < vector.size(); i++)
            ; // 执行操作
    }
}
复制代码

更正:

复制代码
class CEL_fixed
{
    void method (Vector vector) {
        int size = vector.size();
        for (int i = 0; i < size; i++)
            ; // 执行操作
     }
}
复制代码

7、使用finally释放资源

程序中使用到的资源应当被释放,以避免资源泄漏。这最好在finally块中去做。不管程序执行的结果如何,finally块总是会执行的,以确保资源的正确关闭。

8、设置访问实例内变量的getter/setter方法为final

复制代码
class MAF
{
    public void setSize(int size)
    {
        _size = size;
    }
    private int _size;
}
复制代码

更正:

复制代码
class MAF
{
    final public void setSize(int size)
    {
        _size = size;
    }
    private int _size;
}
复制代码

9、避免不需要的instanceof操作

如果左边的对象的静态类型等于右边的,instanceof表达式返回永远为true。所以也根本不需要做判断。

复制代码
public class UISO
{
    public UISO(){}
}

class Dog extends UISO
{
    void method(Dog dog, UISO u)
    {
        Dog d = dog;
        if (d instanceof UISO)      // always true.
        System.out.println("Dog is a UISO");
        UISO uiso = u;
        if (uiso instanceof Object) // always true.
        System.out.println("uiso is an Object");
    }
}
复制代码

10、少用new关键词创建类的实例

用new关键词创建类的实例时,构造函数链中的所有构造函数都会被自动调用。但如果一个对象实现了Cloneable接口,我们可以调用它的clone()方法。clone()方法不会调用任何类构造函数。
在使用设计模式(Design Pattern)的场合,如果用Factory模式创建对象,则改用clone()方法创建新的对象实例非常简单。例如,下面是Factory模式的一个典型实现:

    public static CreditgetNewCredit()
    {
        return new Credit();
    }

改进后:

    private static Credit BaseCredit = new Credit();

    public static CreditgetNewCredit()
    {
        return (Credit) BaseCredit.clone();
    }

11、避免不需要的强转操作

所有的类都是直接或者间接继承自Object。同样,所有的子类也都隐含的“等于”其父类。那么,由子类造型至父类的操作就是不必要的了。

12、不要在循环中调用synchronized(同步)方法

方法的同步需要消耗相当大的资料,在一个循环中调用它绝对不是一个好主意。

复制代码
public class SYN
{
    public synchronized void method(Object o)
    {
    }

    private void test()
    {
        for (int i = 0; i < vector.size(); i++)
        {
            method(vector.elementAt(i)); // violation
        }
    }

    private Vector vector = new Vector(5, 5);
}
复制代码

更正:

复制代码
public class SYN
{
    public void method(Object o)
    {
    }

    private void test () {
        //在一个同步块中执行非同步方法
        synchronized (vector)
        {
            for (int i = 0; i < vector.size(); i++) {
                method (vector.elementAt(i));  
            }
        }
     }

    private Vector vector = new Vector(5, 5);
}
复制代码

13、将try/catch块移出循环

把try/catch块放入循环体内,会极大的影响性能,性能会有明显的下降。

复制代码
import java.io.FileInputStream;

public class TRY
{
    void method(FileInputStream fis)
    {
        for (int i = 0; i < size; i++)
        {
            try
            { // violation
                _sum += fis.read();
            }
            catch (Exception e)
            {
            }
        }
    }
    private int _sum;
}
复制代码

更正:

复制代码
    void method(FileInputStream fis)
    {
        try
        { // violation
            for (int i = 0; i < size; i++)
            {
                    _sum += fis.read();
            }
        }
        catch (Exception e)
        {
        }
    }
复制代码

14、对于常量字符串,用String代替StringBuffer

常量字符串并不需要动态改变长度。把StringBuffer换成String,如果确定这个String不会再变的话,这将会减少运行开销提高性能。

复制代码
public class USC
{
    String method()
    {
        StringBuffer s = new StringBuffer("Hello");
        String t = s + "World!";
        return t;
    }
}
复制代码

15、不要在循环体中实例化变量

在循环体中实例化临时变量将会增加内存消耗

复制代码
import java.util.Vector;

public class LOOP
{
    void method(Vector v)
    {
        for (int i = 0; i < v.size(); i++)
        {
            Object o = new Object();
            o = v.elementAt(i);
        }
    }
}
复制代码

更正:

复制代码
import java.util.Vector;

public class LOOP
{
    void method(Vector v)
    {
        Object o;
        for (int i = 0; i < v.size(); i++)
        {
            o = v.elementAt(i);
        }
    }
}
复制代码

16、确定StringBuffer的容量

StringBuffer的构造器会创建一个默认大小(通常是16)的字符数组。在使用中,如果超出这个大小,就会重新分配内存,创建一个更大的数组,并将原先的数组复制过来,再丢弃旧的数组。在大多数情况下,你可以在创建StringBuffer的时候指定大小,这样就避免了在容量不够的时候自动增长,以提高性能。

复制代码
public class RSBC
{
    void method()
    {
        StringBuffer buffer = new StringBuffer(); // violation
        buffer.append("hello");
    }
}
复制代码

更正:

复制代码
public class RSBC
{
    void method()
    {
        StringBuffer buffer = new StringBuffer(MAX);
        buffer.append("hello");
    }

    private final int MAX = 100;
}
复制代码

以上对一些经常出现的对效率有所影响Java的优化建议进行了详细的描述,其实在实践过程中仍然有许多大家需要注意和优化的地方,譬如:使用System.arraycopy()代替通过来循环复制数组;为Vectors和Hashtables定义初始大小;查找单个字符的话,用charAt()代替startsWith();对于boolean值,避免不必要的等式判断等等,这些都能或多或少的提高效率。对于未涉及的Java优化的最佳实践,在实际项目组编写Java的过程中,通过跟踪程序,精确到平台程序的具体方法,从执行效率和算法逻辑两方面进行优化。

分享到:
评论

相关推荐

    4本高清中文版Java性能优化经典书籍

    Java性能优化是IT行业中至关重要的一个领域,尤其是在大型企业级应用和互联网服务中,高效的Java代码能够显著提升系统运行效率,降低服务器资源消耗。以下是对这四本经典书籍中的核心知识点的详细介绍: 1. **...

    阿里巴巴Java性能调优实战(2021-2022华山版)+Java架构核心宝典+性能优化手册100技巧.rar

    性能优化手册是一套java性能学习研究小技巧,包含内容:Java性能优化、JVM性能优化、服务器性能优化、数据库性能优化、前端性能优化等。 内容包括但不限于: String 性能优化的 3 个小技巧 HashMap 7 种遍历方式...

    大话JAVA性能优化

    但根据标题《大话JAVA性能优化》和描述“虽然有些地方可能过时,但是还是可以一读”以及标签“java 优化”,可以推断出书籍内容可能围绕Java编程语言的性能优化相关知识。基于这些信息,我们可以构建关于Java性能...

    java性能优化教程

    Java性能优化是提升软件效率和用户体验的关键环节,尤其是在大规模应用和高并发场景中。本教程将深入探讨如何通过各种技术和策略来优化Java程序,确保其高效运行。 首先,理解Java性能的基础是JVM(Java虚拟机)。...

    Java 性能优化实战 21 讲2021年

    │ 开篇词 Java 性能优化,是进阶高级架构师的炼金石.mp4 │ 02 理论分析:性能优化有章可循,谈谈常用的切入点.mp4 │ 03 深入剖析:哪些资源,容易成为瓶颈?.mp4 │ 04 工具实践:如何获取代码性能数据?....

    大话Java性能优化

    具体 包括: 性能 优化 策略、 程序 编写 及 硬件 服务器 的 基础 知识、 Java API 优化 建议、 算法 类 程序 的 优化 建议、 并行 计算 优化 建议、 Java 程序 性能 监控 及 检测、 JVM 原理 知识、 其他 相关 ...

    大话java性能优化 周明耀 完整版

    《大话java性能优化》是周明耀先生的一本深入探讨Java性能调优的专业书籍,其主要内容涵盖了Java程序设计中的各种性能优化策略和技术。这本书旨在帮助开发者理解和掌握如何提升Java应用的运行效率,减少资源消耗,...

    Java程序性能优化

    《Java程序性能优化:让你的Java程序更快、更稳定》共6章,先后从软件设计、软件编码、JVM调优以及程序故障排斥等方面介绍针对Java程序的优化方法。第1章介绍性能的基本概念、定律、系统调优的过程和注意事项。第2章...

    Java 性能优化 一书源码

    Java性能优化是软件开发中的一个关键领域,尤其是在大型企业级应用和高并发系统中。《Java性能优化》一书深入探讨了如何通过各种技术提升Java应用程序的效率和响应速度。以下是一些基于书籍源码和相关文件名的关键...

    10种java性能优化方案.docx

    ### Java性能优化方案详解 #### 一、理解性能优化的重要性 在现代软件开发中,特别是在Java领域,性能优化是一项至关重要的任务。随着系统的复杂性和规模不断增长,优化不仅仅是提高用户体验那么简单,更是确保...

    Java性能优化实战视频全集

    ### Java性能优化实战知识点概述 #### 一、理论分析篇 **1.1 性能优化的衡量指标及注意事项** - **衡量指标**: 包括响应时间、吞吐量、资源利用率等。 - **注意事项**: 在进行性能优化时,需确保优化方案不会引入...

    java程序性能优化

    《Java程序性能优化:让你的Java程序更快、更稳定》以Java性能调优为主线,系统地阐述了与Java性能优化相关的知识与技巧。  《Java程序性能优化:让你的Java程序更快、更稳定》共6章,先后从软件设计、软件编码、...

    大话JAVA性能优化.pdf

    大话Java性能优化》主要提供Java性能调优方面的参考建议及经验交流。作者力求做到知识的综合传播,而不是仅仅只针对Java虚拟机调优进行讲解,另外力求每一章节都有实际的案例支撑。具体包括:性能优化策略、程序编写...

    《Java程序性能优化》(葛一鸣)PDF版本下载.txt

    根据提供的文件信息,我们可以推断出这是一本关于Java程序性能优化的书籍,作者是葛一鸣,并提供了该书PDF版本的下载链接。虽然没有具体的书籍内容,但基于标题、描述以及通常这类书籍会涉及的主题,我们可以总结出...

    大话Java性能优化.epub

    大话java性能优化,pdf版!

Global site tag (gtag.js) - Google Analytics