性能優化一點總結

個人管理方面

1、形成體系化的思想。

當做一件事(開發一個系統、解決一個問題)的時候,可以按照一定的體系去下手,這個體系可以理解爲思維意識。少了很多無從下手、從零開始的過程,從而提升效率。這一點事需要個人長久的總結和豐富的經驗!

2、開闊自己的視野。

從不同方面去尋找自己解決問題的思路,增加自己的選擇空間,會讓你權衡更全面,分析更透徹,從而理解更深入,解決問題也更到位。做技術,不能只看技術!一個技術大牛,多少都會對歷史,對藝術有一些瞭解。

技術方面

1、代碼

很多技術人員拿到一個性能優化的需求以後,都會向緩存、分庫分表、異步、多線程、JVM優化等方向去思考。其實,很多時候應該從代碼入手。代碼優化的點很多很多,舉幾個例子:

1、當已經知道list大小的時候,直接指定list大小,可以有效避免list默認大小不夠,而進行復制擴容。
2、變量聲明的位置能局部不全局,可以有效避免長久佔用內存而不能被GC回收。
3、for循環裏大量聲明變量,以致於消耗內存。
等等吧

所以,要多加註意代碼層面的優化,優化的空間很大,很可能代碼優化之後就能滿足性能要求,而不必增加設備來支持訪問量!

2、SQL優化

SQL優化,個人認爲可以從五個層面入手。

*SQL語句優化
    關鍵字的使用like、join、in、exist
*SQL索引優化
    索引的創建、索引的大小設置
*SQL引擎優化
    根據業務需求,選擇最適合的引擎
*數據庫設計優化
    我個人認知,主要是範式的設計。可以適當冗餘數據,以減少數據庫操作。
*數據庫連接池優化
    連接池監控數、連接池方案的選擇(這一塊個人沒使用過)

3、緩存優化

緩存在一個系統裏或多或少都會涉及的。至於什麼數據放入緩存,放入一個什麼樣的緩存,都是值得仔細斟酌的。 使用緩存的情況,個人感覺有兩種:

短時間內相同數據重複查詢多次且數據更新不頻繁,這個時候可以選擇先從緩存查詢,查詢不到再從數據庫加載並回設到緩存的方式。
高併發查詢熱點數據,後端數據庫不堪重負。

選型考慮:

如果數據量小,並且不會頻繁地增長又清空(這會導致頻繁地垃圾回收),那麼可以選擇本地緩存。具體的話,如果需要一些策略的支持(比如緩存滿的逐出策略),可以考慮Ehcache;如不需要,可以考慮HashMap;如需要考慮多線程併發的場景,可以考慮ConcurentHashMap。
目前從資源的投入度、可運維性、是否能動態擴容以及配套設施來考慮,我們優先考慮Tair。除非目前Tair還不能支持的場合(比如分佈式鎖、Hash類型的value),我們考慮用Redis。

當然,使用緩存後,會面臨很多問題,最大的一個問題就是數據一致性。這些就可以根據業務需要而制定不同的方案。

4、多線程

在一個系統裏,在一定情況下使用多線程可以加快響應時間,比如一些異步任務,啓動多線程去處理就好了,還有一些離線任務也不需要等待完成再返回等等。但是線上對響應時間要求較高的場合,儘量少用多線程,尤其是服務線程需要等待任務線程的場合(很多重大事故就是和這個息息相關),如果一定要用,可以對服務線程設置一個最大等待時間。

使用多線程又帶來另一個問題,就是代碼的複雜性。所以,建議如果單機單線程能夠滿足業務需求的儘量使用單機單線程,如果滿足不了,則可以使用單機多線程,如果依然不能滿足,再考慮多機多線程。

使用多線程時,可以考慮使用線程池,線程池的優點有兩個:

1、提高性能,節省線程創建和銷燬的開銷,節省資源。
2、可以利用線程池完成一些功能,比如限流。可以保障機器極限壓力下的穩定處理能力。

5、JVM調優

JVM是Java WEB項目的基石,可以根據項目特點進行JVM調優。我所瞭解到的,只是調整一些GC回收機制和回收策略。比如新生代與老生代比值、eden與survivor比值、觸發cms回收的old區比率閾值等。比如把大對象放入老年代等等。

當然,調優的路上很遠也很長。包括技術的選型,監控的使用,軟件的使用甚至硬件的使用。今天簡單說這麼多!

更多精彩內容,歡迎關注微信公衆號:Java小筆記(ijavanote)



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