实现有价值的IT服务
全部博文(709)
分类: Java
2006-09-04 14:13:44
第一:Java程序设计风格
1.1Java文件名和文件组织结构
每一个java源文件由下面的顺序构成:
1) 文件注释头
2) 包名
3) 引入(import)声明
4) 类(class)或接口(interface)的声明部分
1.2Java文件注释头
/******************************************** * * * * @authod * @since * @version * @date ******************************************/ |
1.3包的声明与引用
1.4类与接口的声明
1.5Java源文件编排格式
1.5.1代码行长度与折行规则
1.6程序注释
1.7变量的声明初始化与放置
1.8Java程序语句编写规则
1.8.1简单语句
1.8.2复合语句
if-else
switch
for
while
do-while
try-catch
try-catch-finally
1.9空格与空行的应用规则
1.10变量、方法与常量的命名规则
变量:
方法:
常量:
1.11Java编程实践
第二:内存管理
2.1垃圾回收
一个对象创建后被放置在JVM的堆内存中,当永远不再引用这个对象时,它被JVM在堆内存中回收。被回收的对象不能再生,同时也没有办法通过程序语句释放他们。
当对象在JVM运行空间中无法通过根集合到达时,这个对象被称为垃圾对象。根集合是有类中的静态引用域与本地引用域组成的
JVM管理的两种类型的内存:对内存(heap)和栈内存(stack)。堆内存主要用来存储程序在运行时创建或实例化的对象与变量,而栈内存则是用来存储程序代码中声明为静态(static)或(非静态)的方法。
堆内存(heap)通常被分成两个区域:新对象(new object)与老对象(old object)区域。
新对象区域又可以细分为三个小区域:伊甸园(Eden)区域、From区域与To区域。伊甸园区域用来保存新创建的对象,就像堆栈一样,当区域中的对象满了之后,JVM系统将做可达性测试,检测哪些对象由根集合出发是不可达的,这些对象就可被JVM回收,并且将其从伊甸园区域拷贝到To区域,此时一些对象将发生状态交换,有的对象就从To区域被转移到From区域,此时From区域就有了对象。
在老对象区域中的对象仍然会有一个较长的生命周期,但经过一段时间后,这些对象就会变成短命对象,也就是垃圾对象,从而被JVM回收,建议不要频繁地强制系统做垃圾回收,这样会影响系统的整体性能。
2.2JVM中对象的生命周期
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) 尽量在合适的场景下使用对象池技术以提高系统性能,缩减系统开销,但是要注意对象池的尺寸不宜过大,及时清除无效对象释放内存资源,综合考虑应用运行环境的内存资源限制,避免过高估计运行环境所提供内存资源的数量。
2.3Java的finalize方法
2.4数组的创建
2.5共享静态变量存储空间
2.6对象重用与GC
2.7RMI与Transient
2.8不要提前创建对象
2.9JVM内存参数调优
.服务器:前提内存1G 单CPU
可通过如下参数进行调整:-server 启用服务器模式(如果CPU多,服务器机建议使用此项)
-Xms,-Xmx一般设为同样大小。 800m
-Xmn 是将NewSize与MaxNewSize设为一致。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 设置后可以使用并行清除收集器
-XX:UseAdaptiveSizePolicy 与上面一个联合使用效果更好,利用它可以自动优化新域大小以及救助空间比值
2.10Java程序设计中有内存管理的其他经验
第三:表达式、语句与保留字
3.1表达式
3.2Java语言中的保留字
static
super
final
synchronized
instanceof
3.3判断语句与循环语句
采用循环语句的几点建议:
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类逻辑判断移到循环之外,以提高应用性能。
3.4正则表达式
第四:Java核心类与性能优化
4.1 散列表类与性能优化
4.1.1 线程同步散列表
线程安全:Vector
非线程安全:ArrayList
4.1.2 设置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)") ; } } |
4.1.3 ArrayList与LinkList
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)) ; } } |
4.2 String类与性能优化
4.2.1 字符串累加与性能优化(优化效果非常明显)
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)) ; } } |
4.2.2 字符串的length()方法与性能优化
不要在循环语句中调用String 的length()方法来获取字符串长度
4.2.3 toCharArray() 方法与性能优化
4.2.4 字符串转化为数字
不要在循环中转换类型
4.3 系统I/O类
4.3.1 Java语言中输入与输出流
Java语言I/O类:二进制输入/输出 和 字符数据输入/输出
二进制输入/输出:InputStream/OutputStream
字符数据输入/输出:Reader/Writer
4.3.2 通过系统缓冲流类提高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() ; } } } |
4.3.3 通过自定制缓冲区提高I/O操作效率
|
4.3.4 通过压缩流提高I/O操作效率
|
4.4 其他
4.4.1 数据格式化与性能优化
4.4.2 获取文件信息与性能优化
第五:JNI程序设计与性能优化
第六:类与接口
6.1 类的构造器
6.1.1构造器编写规则
避免在类的构造器中初始化其他类
不要给构造器误添加返回值
尽量避免在构造器中对静态变量做赋值操作
不要在类的构造器中创建类的实例
6.2 类的继承法则
6.2.1单线继承规则
Class A implements interfaceA,interfaceB{ } |
6.2.2包内部继承规则
6.2.3逻辑包含继承规则
6.3 抽象类与接口
抽象类与接口不能给实例化
接口中与抽象类都不可以独立运行,他们都不能作为应用的主类
接口中可以有属性,抽象类中也可以有属性
6.4继承与组合的应用时机
6.5 接口与抽象类的应用时机
6.6 内部类
第七:JSP与Servlet性能优化
7.1提升JSP应用性能
7.1.1优化jspInit()方法
要理解jsp编译、转换的流程和原理;理解servlet的生命周期,内存控制特点。
<%@ page isThreadSaft=”true”%>比较<%@ page isThreadSaft=”false”%>
一个jsp页面,仅在第一次被请求时做一次初始化操作,而且在整个生命周期中都不会再一次初始化。第一次编译后该servlet 都会执行jspInit()方法。
7.1.2通过优化_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自动装载机制
7.1.3JSP高级知识
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) ;
%>
7.2提升Servlet应用性能
7.2.1提高Servlet应用性能的方法和提高jsp性能方法一样
7.2.2合理缓冲静态数据与动态数据
7.2.3改善Servlet应用性能的方法
7.2.4Filter Servlet 与Listener Servlet
第八:EJB与高性能应用
第九:JMS性能优化
第十:JDBC与性能优化
第十一:软件结构、设计模式与性能优化
11.1模式简介
抽象工厂(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)--
11.2常用模式的Java实现与结构优化
11.2.1单元(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; } } |
11.2.2抽象工厂模式的结构优化(创建模式)
该模式提供一个创建一系列相关或者相互依赖对象的接口,而无须指定它们具体的类。它拥有比工厂方法模式更高的抽象性,是所有工厂模式中最为抽象和最具一般性的工厂状态。
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(); |
11.2.3适配器模式的结构优化(结构模式)
适配器可以将一个类的接口转换成调用方希望的另外一个接口,从而解决两个已有接口之间不兼容的问题。
被适配类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() ; |
11.2.4代理模式的结构优化(结构模式)
代理模式可以给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用
//抽象目标接口 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(){ } } |
11.2.5桥接模式的结构优化(结构模式)
桥接模式可以把两个互相不可到达的对象,搭起一座起到连通作用的桥梁。这两个不可到达的对象就是抽象与实现。而桥接的真正目的是将要抽象与实现分离,这样抽象与实现分开并可以独立演化。
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() } //具体对象 |
11.2.6命令模式的结构优化(行为模式)
在调用命令对象时,调用者根本没有与具体的命令对象产生联系,而只是和接口打交道,遵从了“对接口编程,而不对实现编程”的原则
|
11.2.7观察者模式的结构优化(行为模式)
|
11.2.8责任链的结构优化(行为模式)
|
11.2.9中介者模式的结构优化
|
11.2.10访问者模式的结构优化
|
11.2.11任务分配中心模式
|
11.3 J2EE中的模式与性能优化
11.3.1服务定位模式与性能优化
|
11.3.2会话门面模式与性能优化
|
11.3.3消息门面模式与性能优化
|
11.3.4返回值打包模式与性能优化
|
11.3.5返回值包装工厂模式与性能优化
|
11.3.6值列表处理器模式与性能优化
|
11.3.6复合实体模式与性能优化
|