Java程序代碼調優


1.1.1 通用代碼調優
1.1.2 減小沒有必要的操作
  對象的創建是個很昂貴的工作,所以我們應當儘量減少對象的創建,在需要的時候聲明它,初始化它,不要重複初始化一個對象,儘量能做到再使用,而用完後置null有利於垃圾收集。讓類實現Cloneable接口,同時採用工廠模式,將減少類的創建,每次都是通過clone()方法來獲得對象。另外使用接口也能減少類的創建。對於成員變量的初始化也應儘量避免, 特別是在一個類派生另一個類時。
  異常拋出對性能不利。拋出異常首先要創建一個新的對象。Throwable接口的構造函數調用名爲, fillInStackTrace()的本地(Native)方法,fillInStackTrace()方法檢查堆棧,收集調用跟蹤信息。只要有異常被拋出,VM就必須調整調用堆棧,因爲在處理過程中創建了一個新的對象。 異常只能用於錯誤處理,不應該用來控制程序流程。
  此外, 建議關閉Debug輸出,儘量少用串行化、同步操作和耗時昂貴的服務(如Date())。
1.1.3 使用合適的類型
  當原始類型不能滿足我們要求時,使用複雜類型。String和StringBuffer的區別自不必說了,是我們使用最多的類型,在涉及到字符運算時,強烈建議使用StringBuffer。在做String匹配時使用intern()代替equal()。
  帶有final修飾符的類是不可派生的, 如果指定一個類爲final,則該類所有的方法都是final。
  Java編譯器會尋找機會內聯所有的final方法,這將能夠使性能平均提高50%。類的屬性和方式使用final或者static修飾符也是有好處的。
  調用方法時傳遞的參數以及在調用中創建的臨時變量都保存在棧(Stack)中,速度較快。所以儘量使用局部變量。
  ArrayList和Vector,HashMap和Hashtable是我們經常用到的類,前者不支持同步,後者支持同步,前者性能更好,大多數情況下選擇前者。
1.1.4 儘量使用pool,buffer和cache
  使用pool、buffer和cache能大大提高系統的性能,這在J2EE的大部分技術中都是適用的。
  在WebLogic中就大量使用了池:JDBC Connection Pool、Socket Pool、Object Pool和Thread Pool。I/O操作中,buffer是必須的,特別是對大文件的操作,不然容易造成內存溢出。字節操作最快,所以儘可能採用write(byte []),Buffered FileOutputStream比Buffered FileWriter要快,因爲FileWriter需要Unicode到Byte的轉換。
  而後面講到的JDBC、JSP、EJB和JMS我們都非常建議使用buffer和cache。爲HttpServletResponse設置buffersize,使用wl-cache,緩存在JNDI樹上獲取的對象等等。
  此外,使用JDK 1.4的非阻塞I/O對性能也有很大提高。
1.2 JDBC代碼調優
1.2.1 嚴格資源使用
  JDBC代碼調優最大的原則就是使用WebLogic的連接池,而不是自己直連數據庫。在我接觸的很多自己實現連接池的項目中,大部分遇到死鎖和連接泄漏的問題,最後得不得修改代碼。而WebLogic提供了功能強大,性能良好的數據庫連接池,我們要做的只是封裝一個連接管理類,從JNDI樹上獲取數據源並緩存,得到連接,並提供一系列關閉數據庫資源的方法。
  對任何資源使用的原則是用完即關,不管是數據庫資源、上下文環境,還是文件。數據庫資源的泄漏極易造成內存泄漏,乃至系統崩潰。在使用完數據庫資源後依次關閉ResultSet,Statement和Connection,而在一個數據庫連接多次進行數據庫操作時要特別注意ResultSet和Statement依次關閉。
try{
  //open connection
  pstmt =conn.prepareStatement(strSql1);
  pstmt.executeUpdate();
  pstmt.close();
  pstmt =conn.prepareStatement(strSql2);
  rs=pstmt.executeQuery();
  while (rs.next()){
  //process
 }
rs.close();
pstmt.close();
 }catch(Exception e){
  //close rs,psmt,con
}finally{
  //close rs,psmt,con
}
1.2.2 實用技巧
  在JDBC操作中還有一些小的技巧跟大家分享:由於獲取連接時默認自動提交方式,使用connection.setAutoCommit(false) 關閉自動提交,使用PreparedStatement,批量更新,業務複雜或者大數據量操作時使用存儲過程,儘量使用RowSet,此外設置記錄集讀取緩存FetchSize和設置記錄集讀取方向FetchDirection對性能也有一定的提高。
1.2.3 優化SQL語句
  SQL語句的優化牽涉到很多數據庫的知識,需要與索引配合,因此需要DBA對代碼中的SQL進行檢查測試。常見的,select *不提倡使用,效率極差,建議顯式獲取列,即使是所有字段也應羅列,而取總數時使用count(*),爲提高cache的命中率,儘量做到SQL重用。對於大數據量的查詢,可以充分利用Oracle數據庫的特性,每次取出m-n行的數據,實現分頁查詢。另外,提高性能的好選擇可能就是把所有的字符數據都保存爲Unicode,Java以Unicode形式處理所有數據,因此,數據庫驅動程序不必再執行轉換過程。
1.3 Web代碼調優
1.3.1 HttpSession的使用
  應用服務器保存很多會話時,容易造成內存不足,所以儘量減少session的使用,放置session
裏的對象不應該是大對象,最好是簡單小對象,實現串行化接口。當會話不再需要時,應當及時調用invalidate()方法清除會話。而當某個變量不需要時,及時調用removeAttribute()方法清除變量。請勿將EJB對象放置在session中。
1.3.2 JSP代碼調優
  目前,在JSP頁面中引入外部資源的方法主要有兩種:include指令,以及include動作。 include指令:例如,該指令在編譯時引入指定的資源。在編譯之前,帶有include指令的頁面和指定的資源被合併成一個文件。被引用的外部資源在編譯時就確定,比運行時才確定資源更高效。
include動作:例如。該動作引入指定頁面執行後生成的結果。由於它在運行時完成,因此對輸出結果的控制更加靈活。但是,只有當被引用的內容頻繁地改變時,或者在對主頁面的請求沒有出現之前,被引用的頁面無法確定時,使用include動作才合算。
  對於那些無需跟蹤會話狀態的jsp,關閉自動創建的會話可以節省一些資源。使用如下page指令: ;儘量不要將JSP頁面定義爲單線程,應設置爲;在JSP頁面最好使用輸出緩存功能,如: ;儘量用wl:cache定製標記來緩存靜態或相對靜態的內容,緩存jsp:include操作的結果能顯著提高應用程序的運行性能。
1.3.3 Servlet代碼調優
  Servlet代碼調優比較簡單:在Servlet之間跳轉時,forward比sendRedirect更有效;設置 HttpServletResponse 緩衝區,如:response.setBufferSize(20000);在init()方法裏緩存靜態數據,而在destroy()中釋放它;建議在 Servlet裏使用ServletOutputStream輸出圖片等對象;避免在Servlet和Jsp中定界事務等。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章