Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2552117
  • 博文数量: 709
  • 博客积分: 12251
  • 博客等级: 上将
  • 技术积分: 7905
  • 用 户 组: 普通用户
  • 注册时间: 2005-07-17 00:00
个人简介

实现有价值的IT服务

文章存档

2012年(7)

2011年(147)

2009年(3)

2008年(5)

2007年(74)

2006年(431)

2005年(42)

分类: Java

2006-09-04 14:13:44

第一:Java程序设计风格

11Java文件名和文件组织结构

每一个java源文件由下面的顺序构成:

1)  文件注释头

2)  包名

3)  引入(import)声明

4)  类(class)或接口(interface)的声明部分

 

12Java文件注释头

/********************************************

*

*

*

* @authod

* @since

* @version

* @date

******************************************/

 

13包的声明与引用

 

14类与接口的声明

 

15Java源文件编排格式

 

151代码行长度与折行规则

 

16程序注释

 

17变量的声明初始化与放置

 

18Java程序语句编写规则

181简单语句

 

182复合语句

if-else

switch

for

while

do-while

try-catch

try-catch-finally

 

19空格与空行的应用规则

 

110变量、方法与常量的命名规则

变量:

方法:

常量:

 

111Java编程实践

 

第二:内存管理

21垃圾回收

一个对象创建后被放置在JVM的堆内存中,当永远不再引用这个对象时,它被JVM在堆内存中回收。被回收的对象不能再生,同时也没有办法通过程序语句释放他们。

    当对象在JVM运行空间中无法通过根集合到达时,这个对象被称为垃圾对象。根集合是有类中的静态引用域与本地引用域组成的

JVM管理的两种类型的内存:对内存(heap)和栈内存(stack)。堆内存主要用来存储程序在运行时创建或实例化的对象与变量,而栈内存则是用来存储程序代码中声明为静态(static)或(非静态)的方法。

    

堆内存(heap)通常被分成两个区域:新对象(new object)与老对象(old object)区域。

新对象区域又可以细分为三个小区域:伊甸园(Eden)区域、From区域与To区域。伊甸园区域用来保存新创建的对象,就像堆栈一样,当区域中的对象满了之后,JVM系统将做可达性测试,检测哪些对象由根集合出发是不可达的,这些对象就可被JVM回收,并且将其从伊甸园区域拷贝到To区域,此时一些对象将发生状态交换,有的对象就从To区域被转移到From区域,此时From区域就有了对象。

在老对象区域中的对象仍然会有一个较长的生命周期,但经过一段时间后,这些对象就会变成短命对象,也就是垃圾对象,从而被JVM回收,建议不要频繁地强制系统做垃圾回收,这样会影响系统的整体性能。

 

22JVM中对象的生命周期

 

JVM中对象的生命周期大致可分为7个阶段:创建阶段(Creation)、应用阶段(Using)、不可视阶段(Invisible)、不可到达阶段(Unreachable)、可收集阶段(Collected)、终结阶段(Finalized)、释放阶段(Free)。

     创建阶段

系统通过下面的步骤,完成创建对象的过程:

1       为对象分配存储空间。

2       开始构造对象。

3       递归调用其超类的构造方法。

4       进行对象实例初始化与变量初始化。

5       执行构造方法体。

创建对象时几个关键应用规则:

1       避免在循环体中创建对象,即使对象占用的内存空间不大。

2       尽量及时使对象符合垃圾回收标准。

3       不要采用过深的继承层次。

4       访问本地变量优于访问类中的变量。

     应用阶段

在应用阶段,对象具备下列特征:

1       系统至少维护对象的一个强引用(Strong Reference);

2       所有对该对象的引用全部是强引用,除非我们显示使用了软引用(Soft Reference)、弱引用(Weak Reference)或虚引用(Phantom Reference)。

强引用是指JVM内存管理器从根引用集合(Root set)出发遍寻堆中所有到达对象的路径。当到达对象的任意路径都不含有引用对象时,这个对象的引用就被称为强引用。

 

软引用具有较强的引用功能,只有当内存不够的时候,才回收这类内存。另外这些引用对象还能保证在Java抛出OutOfMemory异常之前,被设置为NULL。它可以用于实现一些常用资源的缓存,实现Cache的功能,保证最大限度的试用内存而不引起OutOfMemory。但在某些时候对软引用的试用会降低应用程序的运行效率与性能。

 

弱引用对象与Soft引用对象的最大不同就在于:GC在进行回收时,需要通过算法检查是否回收Soft引用对象,而对于Weak引用对象,GC总是进行回收。Weak引用对象常用于Map结构中,引用占用内存空间比较大的对象,一旦对象的强引用为null时,这个对象的引用就不存在了,GC能够快速回收该对象。

 

虚引用的用途较少,主要用于辅助finalize函数的使用。

     不可视阶段

 

当一个对象处在不可视阶段,说明我们不能在其它区域的代码中引用它,此时应该主动将其设置为空,帮助JVM及时地发现这个垃圾对象,并且回收系统资源。

     可收集阶段、终结阶段与释放阶段

对象可能处于三种情况:

1       回收器发现该对象已经不可到达。

2       Finalize方法已经被执行。

3       对象空间已被重用。

Java程序设计中有关内存管理的其它经验:

1       最基本的建议就是尽早释放无用对象的引用。

2       尽量少用finalize函数。

3       如果需要使用经常用大的图片,可以使用soft应用类型。

4       注意集合数据类型,包括数组、树、图、链表等数据结构,这些数据结构对GC来说,回收更为复杂。另外注意一些全局变量,静态变量,这些变量往往容易造成不必要的内存资源浪费。

5       尽量避免在类的默认构造器中创建、初始化大量对象,防止在调用其自类的构造器时造成不必要的内存浪费。

6       尽量避免强制系统做垃圾回收,增长系统做垃圾回收的最终时间,降低系统性能。

7       尽量避免显示申请数组空间,当不得不显示地申请数组空间时尽量准确的估计出其合理值。

8       尽量在远程方法调用(RMI)类应用开发时使用瞬间值(transient)变量,除非远程调用端需要获取该瞬间值变量的值。

9       尽量在合适的场景下使用对象池技术以提高系统性能,缩减系统开销,但是要注意对象池的尺寸不宜过大,及时清除无效对象释放内存资源,综合考虑应用运行环境的内存资源限制,避免过高估计运行环境所提供内存资源的数量。

 

23Javafinalize方法

 

24数组的创建

 

25共享静态变量存储空间

 

26对象重用与GC

 

27RMITransient

 

28不要提前创建对象

 

29JVM内存参数调优

.服务器:前提内存1G CPU

  可通过如下参数进行调整:-server 启用服务器模式(如果CPU多,服务器机建议使用此项)

  -Xms,Xmx一般设为同样大小。 800m
  -Xmn 是将NewSizeMaxNewSize设为一致。320m
  -XX:PerSize 64m
  -XX:NewSize 320m 此值设大可调大新对象区,减少Full GC次数
  -XX:MaxNewSize 320m
  -XX:NewRato NewSize设了可不设。4
  -XX: SurvivorRatio 4
  -XX:userParNewGC 可用来设置并行收集
  -XX:ParallelGCThreads 可用来增加并行度 4
  -XXUseParallelGC 设置后可以使用并行清除收集器
  -XXUseAdaptiveSizePolicy 与上面一个联合使用效果更好,利用它可以自动优化新域大小以及救助空间比值

 

210Java程序设计中有内存管理的其他经验

 

第三:表达式、语句与保留字

31表达式

 

32Java语言中的保留字

static

super

final

synchronized

instanceof

33判断语句与循环语句

 

采用循环语句的几点建议:

1)当做数组拷贝操作时,采用System.arraycopy()方法完成拷贝操作要比采用循环的方法拷贝操作效率高。

public class ArrayCopyTest{

       public static void main(String args[]){

              long startIndex,endIndex;

              int[] a = new int[2500000] ;

              int[] b = new int[2500000] ;

 

              for (int i = 0; i

                     a[i] = i ;

              }

             

              startIndex = System.currentTimeMillis() ;

              for (int j = 0;j < a.length ;j++){

                     b[j] = a[j] ;

              }

              endIndex = System.currentTimeMillis() ;

 

              System.out.println(endIndex - startIndex + "milli seconds for loop copy") ;

 

              int[] c = new int[2500000] ;

 

              startIndex = System.currentTimeMillis() ;

              System.arraycopy(a,0,c,0,c.length) ;

              endIndex = System.currentTimeMillis() ;

              System.out.println(endIndex - startIndex + "milli seconds for System.arraycopy()") ;

       }

}

 

2)尽量避免在循环中调用高消费方法

3)避免在循环体内存取数组元素

4)在循环中,循环条件尽量采用常量比较,而不要采用对象的方法返回值或者属性

public class ZeroCompareTest{

       public static void main(String args[]){

              long startIndex,endIndex ;

              int[] a = new int[2500000] ;

              int size = a.length ;

              startIndex = System.currentTimeMillis() ;

 

              for (int i = 0;i< size;i++){

                     a[i] =i ;

              }

              endIndex = System.currentTimeMillis() ;

              System.out.println(endIndex - startIndex + "毫秒(no") ;

 

              int[] b = new int[2500000] ;

              startIndex = System.currentTimeMillis() ;

 

              for (int i = 0;i

                     a[i] =i ;

              }

              endIndex = System.currentTimeMillis() ;

              System.out.println(endIndex - startIndex + "毫秒(yes") ;

             

       }

}

 

5)避免在做最终条件比较时采用方法返回值的方法进行判断

6)尽量避免在循环中使用try-catch

7)在循环中尽量将最长的循环放在最内层,最短的放在最外层,以减少循环切换的数量

8)如果循环体内有if-else类逻辑判断,并且循环次数很大,最好将if-else类逻辑判断移到循环之外,以提高应用性能。

34正则表达式

 

第四:Java核心类与性能优化

41 散列表类与性能优化

411 线程同步散列表

线程安全:Vector

非线程安全:ArrayList

 

412 设置ArrayList初始化容量

import java.util.*;

public class SetArraySize{

       public static void main(String args[]){

              final int N=1000000 ;

              Object obj = new Object() ;

              ArrayList list = new ArrayList() ;

             

              long startTime = System.currentTimeMillis() ;

              for(int i = 1;i<=N;i++){

                     list.add(obj) ;

              }

              long endTime = System.currentTimeMillis() ;

             

              System.out.println((endTime - startTime) + "(no)") ;

 

              list = new ArrayList() ;

              startTime = System.currentTimeMillis() ;

//初始化了改数值,可以很大程度的改善性能

              list.ensureCapacity(N) ;

              for(int i=1;i

                     list.add(obj) ;

              }

              endTime = System.currentTimeMillis() ;

              System.out.println((endTime - startTime) + "(yes)") ;

       }

}

 

413 ArrayListLinkList

ArrayList是一个数组对象,LinkedList是一个链表对象

ArrayList通过内部数Object[]实现,LinkedList通过将一系列内部记录连接在一起实现的。

插入的时候ArrayList性能没有LinkedList好(差别非常大)

查找时候ArrayList性能比LinkedList好(差别非常大)

 

import java.util.*;

 

public class InsertElementToList{

       public static void main(String args[]){

              final int N = 25000 ;

              ArrayList a1 = new ArrayList() ;

              long startTime = System.currentTimeMillis() ;

              for(int i = 1;i

                     a1.add(0,new Integer(i)) ;

              }

              long endTime = System.currentTimeMillis() ;

              System.out.println("ArrayList :" + (endTime - startTime)) ;

      

              LinkedList l1 = new LinkedList() ;

              startTime = System.currentTimeMillis() ;

              for (int i = 1 ; i< N ;i++){

                     l1.add(0,new Integer(i)) ;

              }

              endTime = System.currentTimeMillis() ;

              System.out.println("LinkedList:" + (endTime - startTime)) ;

       }

}

 

import java.util.*;

 

public class LookUpElement{

       public static void main(String args[]){

              final int N = 25000 ;

              ArrayList a1 = new ArrayList() ;

              Object  o ;

              for(int i = 0;i

                     a1.add(new Integer(i)) ;

              }

              long startTime = System.currentTimeMillis() ;

              for(int i =0;i

                     o = a1.get(i) ;

              }

              long endTime = System.currentTimeMillis() ;

              System.out.println("ArrayList :" + (endTime - startTime)) ;

      

              LinkedList l1 = new LinkedList() ;

             

              for (int i = 0 ; i< N ;i++){

                     l1.add(new Integer(i)) ;

              }

              startTime = System.currentTimeMillis() ;

              for(int i = 0;i

                     o = l1.get(i) ;

              }

              endTime = System.currentTimeMillis() ;

              System.out.println("LinkedList:" + (endTime - startTime)) ;

       }

}

 

42 String类与性能优化

421 字符串累加与性能优化(优化效果非常明显)

StringBuffer应用

public class AppendString{

       public static void main(String args[]){

                     final int N = 5000 ;

                     long startTime = System.currentTimeMillis() ;

                     String s1 = "" ;

                     for(int i = 1;i<=N;i++){

                                   s1 =s1 +"*" ;

                            }

                    

                     long endTime =System.currentTimeMillis() ;

                    

                     System.out.println("1:" + (endTime - startTime )) ;

                    

                     startTime = System.currentTimeMillis() ;

                     StringBuffer sb = new StringBuffer() ;

                     for(int i =1 ;i<=N ;i++){

                                   sb.append("*") ;

                            }

                    

                     String s2 = sb.toString() ;

                    

                     endTime = System.currentTimeMillis() ;

                     System.out.println("通过StringBuffer:" + (endTime - startTime)) ;

              }

       }

 

422 字符串的length()方法与性能优化

不要在循环语句中调用String length()方法来获取字符串长度

 

423 toCharArray() 方法与性能优化

 

424 字符串转化为数字

不要在循环中转换类型

 

43 系统I/O

431 Java语言中输入与输出流

Java语言I/O类:二进制输入/输出 字符数据输入/输出

二进制输入/输出:InputStream/OutputStream

字符数据输入/输出:Reader/Writer

432 通过系统缓冲流类提高I/O操作效率

import java.io.*;

 

public class ReadWriterWithBuffer{

       public static void main(String[] args){

              ReadWriterWithBuffer rw = new ReadWriterWithBuffer() ;

             

              try{

                     long startTime = System.currentTimeMillis() ;

                     rw.readWrite("c:\\myjava\\err.txt","c:\\myjava\\ok.txt") ;

                     long endTime = System.currentTimeMillis() ;

                     System.out.println("直接 耗时:" +(endTime - startTime)) ;

                    

                     long startTime1 = System.currentTimeMillis() ;

                     rw.readWriteBuffer("c:\\myjava\\err.txt","c:\\myjava\\ok.txt") ;

                    

                     long endTime1 = System.currentTimeMillis() ;

                     System.out.println("缓冲:"+(endTime1 - startTime1)) ;

              }catch(IOException e){

                     e.printStackTrace() ;

              }

             

       }

       //----------------------------------------------------------

       public static void readWrite(String fileFrom,String fileTo)throws IOException{

              InputStream in = null ;

         OutputStream out = null ;

    try{

                            in = new FileInputStream(fileFrom) ;

                            out = new FileOutputStream(fileTo) ;

             

                            while (true){

                                          int bytedata = in.read() ;

                    

                                          if(bytedata == -1)

                                                 break ;

                                                

                                          out.write(bytedata) ;

                                   }

                            }finally {

                                   if(in !=null)

                                                 in.close() ;

                    

                                   if(out !=null)

                                                 out.close() ;

                     }

       }

      

       public static void readWriteBuffer(String fileFrom,String fileTo) throws IOException{

              InputStream inBuffer = null ;

              OutputStream outBuffer = null ;

              try{

                     InputStream in = new FileInputStream(fileFrom) ;

                     inBuffer = new BufferedInputStream(in) ;

                     OutputStream out = new FileOutputStream(fileTo) ;

                     outBuffer = new BufferedOutputStream(out) ;

                    

                     while(true){

                            int bytedata = inBuffer.read() ;

                            if(bytedata == -1)

                                   break ;

                                   out.write(bytedata) ;

                            }

                     }finally{

                            if(inBuffer != null)

                                   inBuffer.close() ;

                                  

                            if(outBuffer !=null)

                                   outBuffer.close() ;

                     }

              }

}

 

 

433 通过自定制缓冲区提高I/O操作效率

 

 

434 通过压缩流提高I/O操作效率

 

 

 

44 其他

441 数据格式化与性能优化

442 获取文件信息与性能优化

 

第五:JNI程序设计与性能优化

 

第六:类与接口

61 类的构造器

611构造器编写规则

避免在类的构造器中初始化其他类

不要给构造器误添加返回值

尽量避免在构造器中对静态变量做赋值操作

不要在类的构造器中创建类的实例

 

62 类的继承法则

621单线继承规则

Class A implements interfaceA,interfaceB{

}

 

622包内部继承规则

623逻辑包含继承规则

 

63 抽象类与接口

抽象类与接口不能给实例化

接口中与抽象类都不可以独立运行,他们都不能作为应用的主类

接口中可以有属性,抽象类中也可以有属性

 

64继承与组合的应用时机

 

65 接口与抽象类的应用时机

 

66 内部类

 

第七:JSPServlet性能优化

 

71提升JSP应用性能

711优化jspInit()方法

要理解jsp编译、转换的流程和原理;理解servlet的生命周期,内存控制特点。

<%@ page isThreadSaft=”true”%>比较<%@ page isThreadSaft=”false”%>

一个jsp页面,仅在第一次被请求时做一次初始化操作,而且在整个生命周期中都不会再一次初始化。第一次编译后该servlet 都会执行jspInit()方法。

 

712通过优化_jspService()方法提高系统性能

a)采用out对象的print()方法替代println()方法

b)采用ServletOutStream对象替换JSPWriter对象

c)采用适当的值初始化out对象缓冲区大小

<%page buffer=”none|8Kb|size in kb”%>

d)正确使用session

       <%page session=”false” buffer=”12kb”%>

       注意:这样设置后该页面不能使用session的任何操作

d)尽量采用forward()重新定向新的jsp

 

e)选择正确的include机制

f)useBean选择正确的活动范围(page,request,session,application

g)缓冲静态数据与动态数据

g)控制会话,不要将大对象存入HttpSession中。HttpSession的对象也尽量释放,最好是设置超时,以控制HttpSession的生存周期。

h)利用线程池技术处理客户请求

i)取消jsp自动装载机制

 

713JSP高级知识

1)设置jsp或者servlet中的输出不被browser保存在cache

<%

response.setHeader(“cache-control”,”no-store”);//http 1.1

response.setHeader(“Pragma”,”no-cache”) ;//http 1.0

response.setDateHeader(“Expires”,0) ;//prevents caching at the proxy server

%>

 

2)jsp中如何设置cookies

cookies是作为http header的一部分被发送的

<%

Cookie mycookie = new Cookie(“username”,”user1”) ;

Response.addCookie(mycookie);

%>

删除cookie

<%Cookie killMyCookie= new Cookie(“mycookie”,null) ;

killMyCookie.setMaxAge(0) ;

killMyCookie.setPath(“/”) ;

response.addCookie(killMyCookie) ;

%>

 

72提升Servlet应用性能

721提高Servlet应用性能的方法和提高jsp性能方法一样

722合理缓冲静态数据与动态数据

723改善Servlet应用性能的方法

724Filter Servlet Listener Servlet

 

第八:EJB与高性能应用

第九:JMS性能优化

第十:JDBC与性能优化

第十一:软件结构、设计模式与性能优化

111模式简介

抽象工厂(Abstract Factory--

单元(Singleton --

原型(Prototype

构建者(Builder

适配器(Adapter--

门面(Facade

桥接(Bridge--

组合(Composite

装饰器(Decorator

共享元(Flyweight

代理(Proxy--

职责链(chain of Responsibility

命令(Command--

工厂方法(Factory Method

解释器(Interpreter

迭代器(Iterator

中介器(Mediator) --

备忘机制(Memento)

观察者(Observer) --

状态(State)

策略(Strategy)

模板方法(Template Method

访问者(Visitor--

 

112常用模式的Java实现与结构优化

1121单元(Singleton 单件模式(创建模式)

保证一个类仅有一个实例,构造方法被声明private

public class SingletonClass

{

       private static SingletonClass instance = new SingletonClass() ;

       private SingletonClass(){

       }

       public static SingletonClass getInstance(){

              if(instance == null){

                     instance = new SingletonClass() ;

              }

              return instance;

       }

       public void finalize(){

              instance = null;

       }

}

 

1122抽象工厂模式的结构优化(创建模式)

该模式提供一个创建一系列相关或者相互依赖对象的接口,而无须指定它们具体的类。它拥有比工厂方法模式更高的抽象性,是所有工厂模式中最为抽象和最具一般性的工厂状态。

Public abstract class Factory{

Public Product create(int type);

}

 

public abstract class Product{

}

 

public class SoldierFactory extends Factory{

public Product create(int type){

return createSoldier(type);

}

private soldier createSoldier(int type){

return new Soldier(type)

}

}

 

public class BattleplanFactory extends Factory{

public Product create(int type){

return createBattleplan{

}

}

)

 

public class Solder extends Product{

public Soldier(int type){

if(type == 1){

}else if(type ==2){

}else{

}

}

}

 

public class Battleplan extends Product{

public Battleplan(int type){

if(type == 1){

}else if(type ==2){

}else{

}

}

}

 

应用:

Factory factory = null;

If(要创建solider工厂){

Factory = new BattleplanFactory();

}

if(要创建Battleplan工厂){

factory = new BattleplanFactory();

}

solider = factory.createSoldier();

battleplan = factory.createMonster();

 

1123适配器模式的结构优化(结构模式)

适配器可以将一个类的接口转换成调用方希望的另外一个接口,从而解决两个已有接口之间不兼容的问题。

被适配类Adaptee

Public class Adaptee{

Public void adapteeMethod(){

}

}

 

目标接口:Target

public interface Target{

public void targetMethod();

}

 

适配器类Adapter

public class Adapter extends Adaptee implements Target{

public void targetMethod(){

}

}

 

下面调用:

Adapter adapter = new Adapter() ;

Adapter.targetMehtod() ;

Adapter.adapteeMethod() ;

 

1124代理模式的结构优化(结构模式)

代理模式可以给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用

//抽象目标接口

Public interface AbstractTarget{

//

public void handleRequest();

}

//代理角色类(Proxy)

public class Proxy implements AbstractTarget{

RealTarget realTarget = new RealTarget() ;

Public Proxy(){

}

public void handleRequest(){

handlePreRequest();

realTarget.handleRequest();

handlePreRequest();

}

private void handlePreRequest(){

}

}

 

//真实目标角色类

public class RealTarget implements AbstractTarget{

public RealTarget(){

}

public void handleRequest(){

}

}

 

1125桥接模式的结构优化(结构模式)

桥接模式可以把两个互相不可到达的对象,搭起一座起到连通作用的桥梁。这两个不可到达的对象就是抽象与实现。而桥接的真正目的是将要抽象与实现分离,这样抽象与实现分开并可以独立演化。

Public abstract class AbstractClass{

Public abstract void abstractMethod() ;

Public ImplInterface getImpl(int type){

If(type == 1)

 Return new ConcreateImplA() ;

}else if (type ==2){

 return new ConcreateImplB() ;

}else{

return new ConcreateImplA() ;

}

}

 

//具体对象(ConcreateObjectA)

public class ConcreateObjectA extends AbstractClass{

public ConcreateObjectA(int type)

{

}

public void abstractMethod()

}

 

//具体对象

 

1126命令模式的结构优化(行为模式)

在调用命令对象时,调用者根本没有与具体的命令对象产生联系,而只是和接口打交道,遵从了“对接口编程,而不对实现编程”的原则

 

 

1127观察者模式的结构优化(行为模式)

 

 

1128责任链的结构优化(行为模式)

 

 

1129中介者模式的结构优化

 

 

11210访问者模式的结构优化

 

 

11211任务分配中心模式

 

 

113 J2EE中的模式与性能优化

1131服务定位模式与性能优化

 

 

1132会话门面模式与性能优化

 

 

1133消息门面模式与性能优化

 

 

1134返回值打包模式与性能优化

 

 

1135返回值包装工厂模式与性能优化

 

 

1136值列表处理器模式与性能优化

 

 

1136复合实体模式与性能优化

 

 

 

阅读(2027) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~