1.没有必要时请不用使用静态变量

使用Java的开发者都知道,当某个对象被定义为stataic变量所引用,这个对象所占有的内存将不会被回收。有时,开发者会将经常调用的对象或者变量定义为static,以便提高程序的运行性能。因此,不是常用到的对象或者变量,不要定义为static类型的变量,尤其是静态类对象的定义,一定要仔细考虑是否有必要。例如

 
  1.  
    public class X{
  2.  
    static Y a = new Y();
  3.  
    }

类X创建了,没有被回收的话,静态变量a一直占用内存。

2.充分利用单例机制

实用单例可以减少对资源的加载,缩短运行的时间,提高系统效率。但是,单例并不是所有地方都适用于。简单来说,单例可以适用于以下两个方面:

1.   控制资源的使用,通过线程同步来控制资源的并发访问;

2.   控制实例的产生,以达到节约资源的目的;

3. 减少对象的创建

尽量避免在经常调用的方法中循环使用new对象,由于系统不仅要花费时间来创建对象,而且还要花时间对这些对象进行垃圾回收和处理。设计模式中的享元模式就是为了减少对象的多次创建而来的。在我们可以控制的范围内,最大限度的重用对象;在有些时候,最好能用基本的数据类型或数组来替代对象。

4.使用final修饰符

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

5.尽量使用局部变量

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

6.处理好包装类型和基本类型两者的使用场所

虽然包装类型和基本类型在使用过程中是可以相互转换,但它们两者所产生的内存区域是完全不同的,基本类型数据产生和处理都在栈中处理,而包装类型是对象,是在堆中产生实例。在集合类对象,有对象方面需要的处理适用包装类型,其他的情况,建议提倡使用基本类型。

7.学会用StringBuilder和StringBuffer
    这个两个类的区别就不用说了吧,单线程使用StringBuilder,多线程情况下使用StringBuffer,这样性能会有很大提升。

7.尽量不要使用finalize方法

实际上,将资源清理放在finalize方法中完成是非常不好的选择。由于GC的工作量很大,尤其是回收Young代内存时,大都会引起应用程序暂停,所以再选择使用finalize方法进行资源清理,会导致GC负担更大,程序运行效率更差。

8.尽量使用基本数据类型代替对象

String str = "hello";

上面这种方式会创建一个“hello”字符串,而且JVM的字符缓存池还会缓存这个字符串。

String str = new String("hello");

此时程序除创建字符串外,str所引用的String对象底层还包含一个char[]数组,这个char[]数组依次存放了h,e,l,l,o

这个问题我也写个一个博客,请查看我写的有关性能优化的博客。

9.学会使用HashMap、ArrayList

HashTable、Vector等使用在多线程的场合,内部使用了同步机制,这个会降低程序的性能。
10. 深入理解HashMap原理

当你要创建一个比较大的hashMap时,充分利用另一个构造函数

public HashMap(int initialCapacity, float loadFactor)避免HashMap多次进行了hash重构,扩容是一件很耗费性能的事,在默认initialCapacity只有16,而 loadFactor是 0.75,需要多大的容量,你最好能准确的估计你所需要的最佳大小,同样的Hashtable,Vectors也是一样的道理。

11.减少对变量的重复计算

for(int i=0;i<list.size();i++)

应该改写为:

for(int i=0,len=list.size();i<len;i++)

或者

for(int i = list.size(); I > -1; i--)

并且在循环中应该避免使用复杂的表达式,在循环中,循环条件会被反复计算,如果不使用复杂表达式,而使循环条件值不变的话,程序将会运行的更快。

12.避免不必要的对象创建

A a = new A();

if(i==1){list.add(a);}

应该改为

if(i==1){

A a = new A();

list.add(a);}

13.尽量在finally块中释放资源

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

14.使用移位来代替乘法或者除法('a/b',仅适合2^n情况)的操作

"/"是一个代价很高的操作,使用移位的操作将会更快和更有效

int num = a / 4;

int num = a / 8;

应该改为

int num = a >> 2;

int num = a >> 3;

但注意的是使用移位应添加注释,因为移位操作不直观,比较难理解

同样的,对于'*'操作,使用移位的操作将会更快和更有效

int num = a * 4;

int num = a * 8;

应该改为

int num = a << 2;

int num = a << 3;

15. 确定StringBuffer的容量

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

如:StringBufferbuffer = new StringBuffer(1000);

16.尽量早释放无用对象的引用

大部分时,方法局部引用变量所引用的对象 会随着方法结束而变成垃圾,因此,大部分时候程序无需将局部,引用变量显式设为null。

例如:

Public void doJob(){

Object obj =new Object();

……

Obj=null;

}

上面这个就没必要了,随着方法doJob()的执行完成,程序中obj引用变量的作用域会被gc回收。但是如果是改成下面:

public void doJob(){

Object obj =new Object();

……

Obj=null;

//执行耗时,耗内存操作;或调用耗时,耗内存的方法

……

}

这时候就有必要将obj赋值为null,可以尽早的释放对Object对象的引用。

17.尽量避免使用split

除非是必须的,否则应该避免使用split,split由于支持正则表达式,所以效率比较低,如果是频繁的几十,几百万的调用将会耗费大量资源,如果确实需要频繁的调用split,可以考虑使用apache的 StringUtils.split(string,char),频繁split的可以缓存结果。

18.ArrayList & LinkedList

一个是线性表,一个是链表,一句话,随机查询尽量使用 ArrayList,ArrayList优于LinkedList,LinkedList还要移动指针,添加删除的操作LinkedList优于 ArrayList,ArrayList还要移动数据,不过这是理论性分析,事实未必如此,重要的是理解好数据结构。

19.尽量使用System.arraycopy ()代替通过来循环复制数组

System.arraycopy()要比通过循环来复制数组快的多

20.尽量缓存经常使用的对象

尽可能将经常使用的对象进行缓存,可以使用数组,或HashMap的容器来进行缓存,但这种方式可能导致系统占用过多的缓存,性能下降,推荐可以使用一些第三方的开源工具,如EhCache,Oscache进行缓存,他们基本都实现了FIFO/FLU等缓存算法。

21.尽量避免非常大的内存分配

有时候问题不是由当时的堆状态造成的,而是因为分配失败造成的。分配的内存块都必须是连续的,而随着堆heap越来越满,找到较大的连续块越来越困难。

22.慎用异常

当创建一个异常时,需要收集一个栈跟踪(stack track),这个栈跟踪用于描述异常是在何处创建的。构建这些栈跟踪时需要为运行时栈做一份快照,正是这一部分开销很大。当需要创建一个 Exception 时,JVM 不得不说:先别动,我想就您现在的样子存一份快照,所以暂时停止入栈和出栈操作。栈跟踪不只包含运行时栈中的一两个元素,而是包含这个栈中的每一个元素。

如果您创建一个 Exception ,就得付出代价。好在捕获异常开销不大,因此可以使用 try-catch 将核心内容包起来。从技术上讲,您甚至可以随意地抛出异常,而不用花费很大的代价。招致性能损失的并不是 throw 操作——尽管在没有预先创建异常的情况下就抛出异常是有点不寻常。真正要花代价的是创建异常。幸运的是,好的编程习惯已教会我们,不应该不管三七二十一就抛出异常。异常是为异常的情况而设计的,使用时也应该牢记这一原则。

Java内存优化和性能优化的几点建议的更多相关文章

  1. Java内存模型及性能优化

    最近在做一个项目的性能优化,遇到好多以前没有关注过的性能问题,一头雾水,今天做个笔记,简单记录下JVM相关的参数设置. 一.JVM内存模型 首先介绍下Java程序具体执行的过程: Java源代码文件( ...

  2. JVM内存模型和性能优化 转

    JVM内存模型和性能优化 JVM内存模型优点 内置基于内存的并发模型:      多线程机制 同步锁Synchronization 大量线程安全型库包支持 基于内存的并发机制,粒度灵活控制,灵活度高于 ...

  3. LeakCanary 内存泄漏 监测 性能优化 简介 原理 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  4. Java高级开发_性能优化的细节

    一.核心部分总结: 尽量在合适的场合使用单例[减负提高效率] 尽量避免随意使用静态变量[GC] 尽量重用对象,避免过多过常地创建Java对象[最大限度地重用对象] 尽量使用final修饰符[内联(in ...

  5. Tomcat多实例集群架构 安全优化和性能优化

    Tomcat多实例 复制tomcat目录 /usr/local/tomcat1 /usr/local/tomcat2 修改多实例配置文件 #创建多实例的网页根目录 mkdir -p /data/www ...

  6. Atitit 提升开发进度大方法--高频功能与步骤的优化 类似性能优化

    Atitit 提升开发进度大方法--高频功能与步骤的优化 类似性能优化 1. 通用功能又可以组合成crud模块1 1.1. 查询(包括步骤,发送查询dsl,通讯返回结果,绑定到表格控件)2 1.2. ...

  7. JVM内存模型和性能优化

    JVM内存模型优点 内置基于内存的并发模型:      多线程机制 同步锁Synchronization 大量线程安全型库包支持 基于内存的并发机制,粒度灵活控制,灵活度高于数据库锁. 多核并行计算模 ...

  8. 性能调优 -- Java编程中的性能优化

    String作为我们使用最频繁的一种对象类型,其性能问题是最容易被忽略的.作为Java中重要的数据类型,是内存中占据空间比较大的一个对象.如何高效地使用字符串,可以帮助我们提升系统的整体性能. 现在, ...

  9. 《嵌入式Linux内存使用与性能优化》笔记

    这本书有两个关切点:系统内存(用户层)和性能优化. 这本书和Brendan Gregg的<Systems Performance>相比,无论是技术层次还是更高的理论都有较大差距.但是这不影 ...

随机推荐

  1. Java之NIO,BIO,AIO

    Hollis知识星球的一些学习笔记,有兴趣的朋友可以微信搜一下 什么是NIO 什么是IO? 它是指计算机与外部世界或者一个程序与计算机的其余部分的之间的接口.它对于任何计算机系统都非常关键,因而所有 ...

  2. Solr7.2的安装与使用

    单机安装Solr服务: https://www.cnblogs.com/LUA123/p/7906774.html extend: install_solr_service.sh 参数说明: 安装脚本 ...

  3. java多线程 --ConcurrentLinkedQueue 非阻塞 线程安全队列

    ConcurrentLinkedQueue是一个基于链接节点的无界线程安全队列,它采用先进先出的规则对节点进行排序,当我们添加一个元素的时候,它会添加到队列的尾部:当我们获取一个元素时,它会返回队列头 ...

  4. JVM 垃圾回收机制和常见算法

    垃圾回收机制:释放那些不再持有引用的对象的内存. 如何判断对象是否需要回收? 引用计数:对象,内存,磁盘空间等被引用次数保存起来,次数为0时将其进行释放. 对象引用遍历:对象应用遍历从一组对象开始,沿 ...

  5. MVC4.0中cshtml中怎么解析html编码

    http://bbs.csdn.net/topics/391060108?page=1 问题描述: 数据库中存储带有格式的文本,如 <span style="color:#333333 ...

  6. Lowest Common Ancestor in a Binary Tree

    二叉树最低公共祖先节点 acmblog If one key is present and other is absent, then it returns the present key as LC ...

  7. P1558 色板游戏

    P1558 色板游戏 题目背景 阿宝上学了,今天老师拿来了一块很长的涂色板. 题目描述 色板长度为L,L是一个正整数,所以我们可以均匀地将它划分成L块1厘米长的小方格.并从左到右标记为1, 2, .. ...

  8. Excel 中 VLOOKUP() 函数小结

    应用场景: 数据仓库上游源系统的数据库表变更,现在需要拆分一部分数据出来,单独放到一张新表中.假设原表为A,新表为B,B表和A表结构大部分一样,只有字段的前缀不同,那么我们如何找出到底有哪些字段不同呢 ...

  9. NandFlash、NorFlash、DataFlash、SDRAM释义

    1. NandFlash和NorFlash       Flash存储芯片,俗称闪存,因其具有非易失性.可擦除性.可重复编程及高密度.低功耗等特点,广泛地应用于手机.数码相机.笔记本电脑等产品.    ...

  10. HDU 5143 DFS

    分别给出1,2,3,4   a, b, c,d个 问能否组成数个长度不小于3的等差数列. 首先数量存在大于3的可以直接拿掉,那么可以先判是否都是0或大于3的 然后直接DFS就行了,但是还是要注意先判合 ...