国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Java極度性能調整

2019-11-18 12:21:16
字體:
來源:轉載
供稿:網友

  有很多介紹基本的java應用性能調整的文章。他們都討論些簡單的技術,諸如使用StringBuffer而不用String,使用synchronized要害字的開銷等等。
  
  這篇文章不再介紹這些東西。相反,我們關注能幫助你的基于Web的應用更快、可升級型更好的技巧。一些技巧很具體,其他的相對簡短,但所有的都很有用。最后以一些你可提供給你的治理者的建議結束。
  
  我寫這篇文章的靈感來自于當我的同事和我一起回憶我們的.com(dot-com)時代的時候——我們如何設計能支持成千上萬的用戶和擁有緊密代碼的系統,我們如何對有侵略性的致命打擊。有時在為復用設計和為性能設計之間有一個權衡。基于我的情況,性能每次都獲勝。即使你的商務顧客無需理解代碼復用,但是他們知道快速(fast-performing)的系統是怎么回事。讓我們開始看看我們的技巧。
  
  如何使用Exception
  Exception降低性能。一個異常拋出首先需要創建一個新的對象。Throwable接口中的構造器調用名為fillInStackTrace()的本地方法。這個方法負責巡檢棧的整個框架來收集跟蹤信息。這樣無論何時有異常拋出,它要求虛擬機裝載調用棧,因為一個新的對象在中部被創建。
  
  異常應當僅用于有錯誤發生時,而不要控制流。
  
  我有機會在一個專門用于無線內容市場的網站(名字故意隱去了)看到一段代碼,其中開發者完全可以使用一個簡單的對照來查看對象是否為空。相反,他或她跳過了這個檢查而實際上拋出Null-PointerException。
  
  不要兩次初始化變量
  Java通過調用獨特的類構造器默認地初始化變量為一個已知的值。所有的對象被設置成null,integers (byte, short, int, long)被設置成0,float和double設置成0.0,Boolean變量設置成false。這對那些擴展自其它類的類尤其重要,這跟使用一個新的要害詞創建一個對象時所有一連串的構造器被自動調用一樣。
  
  對新的要害詞使用優選法則
  正如前面提到的,通過使用一個新的要害詞創建一個類的實例,在這個鏈中的所有構造器將被調用。假如你需要創建一個類的新實例,你可以使用一個實現了cloneable接口的對象的clone()方法。該clone方法不調用任何類的構造器。
  
  假如你已經使用了設計模式作為你的體系結構的一部分,并且使用了工廠模式創建對象,變化會很簡單。下面所列是工廠模式的典型實現。
  
  public static Account getNewAccount() {
  return new Account();
  }
  
  使用了clone方法的refactored代碼看起來可能像下面這樣:
  
  PRivate static Account BaseAccount = new Account();
  public static Account getNewAccount() {
    return (Account) BaseAccount.clone();
  }
  
  以上的思路對實現數組同樣有用。
  
  假如你在應用中沒有使用設計模式,我建議你停止讀這篇文章,趕緊跑到(不要走)書店挑一本四人著的《設計模式》。
  
  在任何可能的地方讓類為Final
  標記為final的類不能被擴展。在《核心Java API》中有大量這個技術的例子,諸如java.lang.String。將String類標記為final阻止了開發者創建他們自己實現的長度方法。
  
  更深入點說,假如類是final的,所有類的方法也是final的。Java編譯器可能會內聯所有的方法(這依靠于編譯器的實現)。在我的測試里,我已經看到性能平均增加了50%。
  
  在任何可能的地方使用局部變量
  屬于方法調用部分的自變量和聲明為此調用一部分的臨時變量存儲在棧中,這比較快。諸如static,實例(instance)變量和新的對象創建在堆中,這比較慢。局部變量的更深入優化依靠于你正在使用的編譯器或虛擬機。
  
  使用Nonblocking I/O
  當前的JDK版本不支持nonblocking I/O API,很多應用試圖通過創建大量的線程(目光長遠得用在池中)來避免阻塞。正如前述,在Java中創建線程有嚴重的開銷。
  
  典型的你可能看到應用中實現的線程需要支持并發I/O流,像Web 服務器,并quote and aUCtion components.
  
  JDK1.4介紹了一個nonblocking I/O包(java.nio)。假如你必須保留在較早版本的JDK,有添加了支持nonblocking I/O的第三方包。
  
  :www.cs.berkeley.edu/~mdw/proj/java-nbio/download.Html.
  
  停止小聰明
  很多開發人員在腦子中編寫可復用和靈活的代碼,而有時候在他們的程序中就產生額外的開銷。曾經或者另外的時候他們編寫了類似這樣的代碼:
  
  public void doSomething(File file) {
  FileInputStream fileIn = new FileInputStream(file);
  // do something
  
  他夠靈活,但是同時他們也產生了更多的開銷。這個主意背后做的事情是操縱一個InputStream,而不是一個文件,因此它應該重寫如下:
  
  public void doSomething(InputStream inputStream){
  // do something
  
  乘法和除法
  我有太多的東東適用于摩爾法則——它聲明CPU功率每年成倍增長。"摩爾法則"表明每年由開發者所寫的差勁的代碼數量三倍增加,劃去了摩爾法則的任何好處。
  
  考慮下面的代碼:
  
  for (val = 0; val < 100000; val +=5) { shiftX = val * 8; myRaise = val * 2; }
  
  假如我們狡猾的利用位移(bit),性能將會六倍增加。這是重寫的代碼:
  
  for (val = 0; val < 100000; val += 5) { shiftX = val << 3; myRaise = val << 1; }
  
  代替了乘以8,我們使用同等效果的左移3位。每一個移動相當于乘以2,變量myRaise對此做了證實。同樣向右移位相當于除以2,當然這會使執行速度加快,但可能會使你的東東以后難于理解;所以這只是個建議。
  
  選擇一個基于垃圾收集實現的虛擬機
  許多人可能會對Java規范不需要實現垃圾收集感到驚奇。設想時代已經是我們都擁有無限內存計算機。總之,垃圾收集器日常事務就是負責發現和拋出(hence garbage)不再需要的對象。垃圾收集必須發現那些對象不再被程序指向,并且使被對象占用的棧內存被釋放掉。它還負責運行任何被釋放對象的finalizer。
  
  垃圾收集故意不答應你釋放并非由你分配的內存,從而幫助你確保程序完整,當JVM確定CPU時間的時間表并且當垃圾收集器運行時,這個進程也產生開銷。
  
  垃圾收集器有兩個不同的步驟執行他們的工作。
  
  實現了定位計算的垃圾收集器在棧中為每一個對象保留一個計數。當一個對象被創建并且對它的一個定位被分配給一個變量,計數增加。當對象越出范圍,定位計數被設置成0并且對象可以被垃圾收集。這個步驟答應參考計數器運行在與程序執行有關的短時間增量內。定位計數在父子彼此擁有定位的應用里運行不正常。每次一個對象刷新時也會有定位計數增加和減少的開銷。
  
  實現了跟蹤的垃圾收集器從根節點開始跟蹤一列定位。對象發現跟蹤是否被標記。在這個過程完成后,知道不可達的任何沒標記的對象可以被垃圾收集。這可能以位圖(bitmap)形式實現或者在對象中被設置標志。此技術參考"Mark and Sweep."(reference:定位,翻譯成“指向”似乎更輕易理解,是Java語言對在用對象的一個跟蹤指針。譯者著)
  
  給你的治理人員提建議
  其他方法可被用來使你的基于Web的應用更快并且更可升級。可實現的最簡單的技術通常是支持cluster的策略。使用cluster,一組服務器能夠一起透明的提供服務。多數應用服務器答應你獲得cluster支持而不需要改變你的應用——一個大的勝利。
  
  當然在執行此步驟之前你可能需要考慮來自你使用的應用服務器提供商附加的許可權利。
  
  當看到cluster策略會有許多額外的事情考慮。經常在體系結構中產生的一個缺點是擁有有狀態會話。假如cluster中的一個服務器或者進程當掉,cluster會舍棄整個應用。為防止此類事情發生,cluster必須給cluster中的所有成員不斷復制會話Bean的狀態。確保你也限制了存儲在會話中的對象的大小和數量,因為這些也需要被復制。
  
  Cluster也答應你分期度量你的Web站點的部分。假如你需要度量靜態部分,你可以添加Web服務器。假如你需要度量動態生成的部分,你可以添加應用服務器。
  
  在你已經把你的系統放入cluster后,下一個讓你的應用跑得更快的建議步驟是選擇一個更好的虛擬機。看看Hotspot虛擬機或者其他的飛速發展中的執行優化的虛擬機。隨同虛擬機,看看更好的編譯器是一個更好的主意。
  
  假如你使用了幾個這兒提到的行業技術插件,并且仍然不能獲得你要的可升級性和高可用性,那么我建議一個可靠的調試策略。策略的第一步是為可能的瓶頸檢查整個體系結構。通常,這在你的作為單線程組件或者有很多輔助連接線組件的UML流圖中很輕易識別出來。
  
  最后的步驟是產生一個整個代碼的具體性能估價。
  
  確保你的治理人員至少為此安排了整個項目時間的20%;否則不足的時間可能不止危及你整個成功的安全,還會導致你向系統引入新的缺點。
  
  許多組織者在適當的位置沒有嚴格意義的測試基礎而歸咎于成本考慮也是錯誤的。確保你的QA環境真實反映你的生產環境,并且你的QA測試考慮以不同的負載測試應用,包括在最大的預期并發用戶時一個基于低負載和一個完全負載的測試。
  
  性能測試,有時測試一個系統的穩定性,可能需要在天天,甚至每周的整個時期的不同關節都運行。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 和顺县| 四子王旗| 中江县| 修文县| 宁河县| 宁海县| 井陉县| 东丰县| 平塘县| 林周县| 宾阳县| 宁城县| 方正县| 大连市| 政和县| 吉安市| 库车县| 隆昌县| 龙游县| 万载县| 英德市| 阜新市| 南城县| 泸水县| 博客| 长岭县| 安阳市| 阿拉善左旗| 绵阳市| 黔江区| 镶黄旗| 元氏县| 澎湖县| 延庆县| 景泰县| 龙州县| 龙州县| 贡山| 兰西县| 云霄县| 云霄县|