第一篇:性能調優(yōu)JDK5.0自帶工具
簡介:
JDK 5.0, 代號老虎,在以往的Java傳統上加入了許多新的設計,給Java語言帶來了一些較大的變化,比如泛型,元數據,可變個數參數,靜態(tài)導入類,新線程架構,自動裝箱/拆箱等等新的以往沒有的新特性。同時,在調試程序和解決性能各種問題方面,JDK5.0同樣加入了多個分析工具來讓開發(fā)者更加方便地調試他們自 己的程序,它們包括了命令行調試工具,圖形界面調試工具等等.JDK5.0包括的調試工具:
我們在這里對JDK5.0的調試工具做大致的概念性的介紹,然后希望通過介紹我自己在實際工作中使用這些工具解決問題的實例來讓大家對這些工具有更深入的了解。
JDK5.0里面加入了jstack, jconsole, jinfo, jmap, jdb, jstat, jps, 下面對這些工具做簡單介紹:
?
?
? ?
?
? ? ? jstack--如果java程序崩潰生成core文件,jstack工具可以用來獲得core文件的java stack和native stack的信息,從而可以輕松地知道java程序是如何崩潰和在程序何處發(fā)生問題。另外,jstack工具還可以附屬到正在運行的java程序中,看到 當時運行的java程序的java stack和native stack的信息, 如果現在運行的java程序呈現hung的狀態(tài),jstack是非常有用的。目前只有在Solaris和Linux的JDK版本里面才有。
jconsole – jconsole是基于Java Management Extensions(JMX)的實時圖形化監(jiān)測工具,這個工具利用了內建到JVM里面的JMX指令來提供實時的性能和資源的監(jiān)控,包括了Java程序的內存使用,Heap size, 線程的狀態(tài),類的分配狀態(tài)和空間使用等等。
jinfo – jinfo可以從core文件里面知道崩潰的Java應用程序的配置信息,目前只有在Solaris和Linux的JDK版本里面才有。jmap – jmap 可以從core文件或進程中獲得內存的具體匹配情況,包括Heap size, Perm size等等,目前只有在Solaris和Linux的JDK版本里面才有。
jdb – jdb 用來對core文件和正在運行的Java進程進行實時地調試,里面包含了豐富的命令幫助您進行調試,它的功能和Sun studio里面所帶的dbx非常相似,但 jdb是專門用來針對Java應用程序的。
jstat – jstat利用了JVM內建的指令對Java應用程序的資源和性能進行實時的命令行的監(jiān)控,包括了對Heap size和垃圾回收狀況的監(jiān)控等等。jps – jps是用來查看JVM里面所有進程的具體狀態(tài), 包括進程ID,進程啟動的路徑等等。另外,還有些其他附帶的工具在這里沒有列出,比如Heap Analysis Tool, kill-3 方法等等,這些在JDK5.0之前就有,同樣也是非常有用的性能調優(yōu)工具,大家可以參照相應的文檔資料來學習,在文章后面也會推薦一些相應的文檔給大家作為參考。好,說了這么多,讓我們來看看JDK5.0自帶的這些工具在現實工作能給我們帶來什么幫助,下面是我和ISV一起共同工作的實際例子,在這里把它們簡單闡述出來,希望對大家有所幫助。? jconsole和jstack使用實例: ?
在做過的項目中,曾經有幾個是使用jstack和jconsole來解決問題的。在下面的例子中,由于部分代碼涉及到公司名字,我使用了xxx來代替。
1.其中的一個是Web2.0的客戶,由于目前Sun Microsystem公司推出的Niagara服務器系列非常適合網絡方面的多線程應用,并且已經在業(yè)界非常出名,所以他們決定使用T2000服務器來測試一下如果應用到他們自己的應用是否能夠獲得出眾的性能。
整個應用的架構如下:
Apache 2.0.59 + Resin EE 2.1.17 + Jdk 1.5.0.07 + Oracle 9 運行的操作系統: Solaris 10 Update 3(11/06), EIS patches包.測試工具:
Apache benchmark tool.在客戶的測試環(huán)境中,我們分別做了Apache, Resin, Solaris的相應調整,其中包括了Apache使用Prefork模式,并且調整了httpd.conf文件里面相應的ServerLimit, ListenBacklog,Maxclient等等值,Resin服務器調整Jvm heap size, 并行回收new generation和old generation, 最大線程數,oracle連接數等等參數,Solaris操作系統做了網絡和系統的相應調整,最終把整套系統搬進了生產環(huán)境,一切順利進行,但當進入其中 的一個論壇系統時卻發(fā)現系統響應時間非常緩慢,用Apache Benchmark Tool加少量壓力得到結果如下,由于是在生產環(huán)境下所以不敢使用大的壓力:
This is ApacheBench, Version 2.0.41-dev <$Revision: 1.121.2.12 $> apache-2.0 Copyright(c)1996 Adam Twiss, Zeus Technology Ltd, http:// http://java.sun.com/j2se/1.5.0/docs/guide/management/jconsole.html http://java.sun.com/docs/hotspot/gc5.0/ergo5.html#0.0.Behavior%20based%20tuning%7Coutline http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html http://java.sun.com/ http://www.java.net/
第二篇:Oracle性能調優(yōu)實踐中的幾點心得
很多的時侯,做Oracle DBA的我們,當應用管理員向我們通告現在應用很慢、數據庫很慢的時侯,我們到數據庫時做幾個示例的Select也發(fā)現同樣的問題時,有些時侯我們會無從下手,因為我們認為數據庫的各種命種率都是滿足Oracle文檔的建議。實際上如今的優(yōu)化己經向優(yōu)化等待(waits)轉型了,實際中性能優(yōu)化最根本的出現點也都集中在IO,這是影響性能最主要的方面,由系統中的等待去發(fā)現Oracle庫中的不足、操作系統某些資源利用的不合理是一個比較好的辦法,下面把我的一點實踐經驗與大家分享一下,本文測重于Unix環(huán)境。
一、通過操作系統的一些工具檢查系統的狀態(tài),比如CPU、內存、交換、磁盤的利用率,根據經驗或與系統正常時的狀態(tài)相比對,有時系統表面上看起來看空閑這也可能不是一個正常的狀態(tài),因為cpu可能正等待IO的完成。除此之外我們還應觀注那些占用系統資源(cpu、內存)的進程。
1、如何檢查操作系統是否存在IO的問題?使用的工具有sar,這是一個比較通用的工具。
Rp1#Sar-u 2 10 即每隔2秒檢察一次,共執(zhí)行20次,當然這些都由你決定了。
示例返回:
HP-UX hpn2 B.11.00 U 9000/800 08/05/03 18:26:32 %usr %sys %wio %idle 18:26:34 80 9 12 0 18:26:36 78 11 11 0 18:26:38 78 9 13 1 18:26:40 81 10 9 1 18:26:42 75 10 14 0 18:26:44 76 8 15 0 18:26:46 80 9 10 1 18:26:48 78 11 11 0 18:26:50 79 10 10 0 18:26:52 81 10 9 0 Average 79 10 11 0 其中的%usr指的是用戶進程使用的cpu資源的百分比,%sys指的是系統資源使用cpu資源的百分比,%wio指的是等待io完成的百分比,這是值得我們觀注的一項,%idle即空閑的百分比。如果wio列的值很大,如在35%以上,說明你的系統的IO存在瓶頸,你的CPU花費了很大的時間去等待IO的完成。Idle很小說明系統CPU很忙。像我的這個示例,可以看到wio平均值為11說明io沒什么特別的問題,而我的idle值為零,說明我的cpu已經滿負荷運行了。
當你的系統存在IO的問題,可以從以下幾個方面解決
♀聯系相應的操作系統的技術支持對這方面進行優(yōu)化,比如hp-ux在劃定卷組時的條帶化等方面。
♀查找Oracle中不合理的sql語句,對其進行優(yōu)化
♀對Oracle中訪問量頻繁的表除合理建索引外,再就是把這些表分表空間存放以免訪問上產生熱點,再有就是對表合理分區(qū)。
2、關注一下內存。
常用的工具便是vmstat,對于hp-unix來說可以用glance,Aix來說可以用topas,當你發(fā)現vmstat中pi列非零,memory中的free列的值很小,glance,topas中內存的利用率多于80%時,這時說明你的內存方面應該調節(jié)一下了,方法大體有以下幾項。
♀劃給Oracle使用的內存不要超過系統內存的1/2,一般保在系統內存的40%為益。
♀為系統增加內存
♀如果你的連接特別多,可以使用MTS的方式
♀打全補丁,防止內存漏洞。
3、如何找到點用系用資源特別大的Oracle的session及其執(zhí)行的語句。Hp-unix可以用glance,top IBM AIX可以用topas 些外可以使用ps的命令。
通過這些程序我們可以找到點用系統資源特別大的這些進程的進程號,我們就可以通過以下的sql語句發(fā)現這個pid正在執(zhí)行哪個sql,這個sql最好在pl/sql developer,toad等軟件中執(zhí)行, 把<>中的spid換成你的spid就可以了。SELECT a.username, a.machine, a.program, a.sid, a.serial#, a.status, c.piece, c.sql_text FROM v$session a, v$process b, v$sqltext c WHERE b.spid=
AND b.addr=a.paddr AND a.sql_address=c.address(+)ORDER BY c.piece
我們就可以把得到的這個sql分析一下,看一下它的執(zhí)行計劃是否走索引,對其優(yōu)化避免全表掃描,以減少IO等待,從而加快語句的執(zhí)行速度。
提示:我在做優(yōu)化sql時,經常碰到使用in的語句,這時我們一定要用exists把它給換掉,因為Oracle在處理In時是按Or的方式做的,即使使用了索引也會很慢。比如:
SELECT col1,col2,col3 FROM table1 a
WHERE a.col1 not in(SELECT col1 FROM table2)可以換成:
SELECT col1,col2,col3 FROM table1 a WHERE not exists(SELECT 'x' FROM table2 b WHERE a.col1=b.col1)
4、另一個有用的腳本:查找前十條性能差的sql.SELECT * FROM
(SELECT PARSING_USER_ID EXECUTIONS, SORTS, COMMAND_TYPE, DISK_READS, sql_text FROM v$sqlarea ORDER BY disk_reads DESC)
WHERE ROWNUM<10;
二、迅速發(fā)現Oracle Server的性能問題的成因,我們可以求助于v$session_wait這個視圖,看系統的這些session在等什么,使用了多少的IO。以下是我提供的參考腳本:
腳本說明:查看占io較大的正在運行的session SELECT se.sid, se.serial#, pr.SPID, se.username, se.status, se.terminal, se.program, se.MODULE, se.sql_address, st.event, st.p1text, si.physical_reads, si.block_changes
FROM v$session se, v$session_wait st, v$sess_io si, v$process pr WHERE st.sid=se.sid
AND st.sid=si.sid AND se.PADDR=pr.ADDR AND se.sid>6 AND st.wait_time=0
AND st.event NOT LIKE '%SQL%' ORDER BY physical_reads DESC 對檢索出的結果的幾點說明:
1、我是按每個正在等待的session已經發(fā)生的物理讀排的序,因為它與實際的IO相關。
2、你可以看一下這些等待的進程都在忙什么,語句是否合理?
Select sql_address from v$session where sid=
你也以用alter system kill session 'sid,serial#';把這個session殺掉。
3、應觀注一下event這列,這是我們調優(yōu)的關鍵一列,下面對常出現的event做以簡要的說明: a、buffer busy waits,free buffer waits這兩個參數所標識是dbwr是否夠用的問題,與IO很大相關的,當v$session_wait中的free buffer wait的條目很小或沒有的時侯,說明你的系統的dbwr進程決對夠用,不用調整;free buffer wait的條目很多,你的系統感覺起來一定很慢,這時說明你的dbwr已經不夠用了,它產生的wio已經成為你的數據庫性能的瓶頸,這時的解決辦法如下: a.1增加寫進程,同時要調整db_block_lru_latches參數 示例:修改或添加如下兩個參數
db_writer_processes=4 db_block_lru_latches=8 a.2開異步IO,IBM這方面簡單得多,hp則麻煩一些,可以與Hp工程師聯系。b、db file sequential read,指的是順序讀,即全表掃描,這也是我們應該盡量減少的部分,解決方法就是使用索引、sql調優(yōu),同時可以增大db_file_multiblock_read_count這個參數。
c、db file scattered read,這個參數指的是通過索引來讀取,同樣可以通過增加db_file_multiblock_read_count這個參數來提高性能。
d、latch free,與栓相關的了,需要專門調節(jié)。
e、其他參數可以不特別觀注。
結篇:匆忙之中寫下了這篇文章,希望能拋磚引玉,能為你的Oracle調優(yōu)實踐帶來幫助。
第三篇:Java程序性能調優(yōu)的基本知識和JDK調優(yōu)
一 基本知識
1.1 性能是什么
在性能調優(yōu)之前,我們首先來了解一下性能是什么?關于性能,我想每個學習過Java的人都能列出幾點,甚至可以夸夸其談。在《Java TM Platform Performance》一書中,定義了如下五個方面來作為評判性能的標準:
1)運算的性能——哪一個算法的執(zhí)行性能最好?
2)內存的分配——程序運行時需要耗費多少內存?
3)啟動的時間——程序啟動需要多長時間?這在Web項目中的影響不大,但要注意部分程序需要部署或運行在客戶端時的情形(比如applet程序)。
4)程序的可伸縮性——在壓力負載的情況下,程序的性能如何?
5)性能的感知——用戶在什么情況下會覺得程序的性能不好?
以上五個方面,在具體的使用場景可以有選擇的去評判。至于這五方面的性能調優(yōu),在后續(xù)的章節(jié)中將會陸續(xù)的給以相應的性能調優(yōu)策略。
1.2 調優(yōu)的規(guī)則
我們只需要關心對我們程序有影響,可以察覺到的性能問題,而不是每一個類中的每一個方法我們都需要想方設法的提高性能。如果程序的性能沒有達到我們所期 望的要求,我們才需要考慮如何優(yōu)化性能。同樣的,晦澀的代碼雖然提高了程序的性能,但同時可能帶給我們的是維護的噩夢。我們需要折中的考慮以上兩種情況,使得程序的代碼是優(yōu)美的,并且運行的足夠快,達到客戶所期望的性能要求。
優(yōu)化代碼甚至會導致不良的結果,Donald Knuth(一位比較牛比較有影響的人物,具體是誰,我也忘了,誰知道,可以告訴我一下,謝謝!)曾說過,“Premature optimization is the root of all evil”。在開始性能調優(yōu)前,需要先指出不優(yōu)化代碼的一些理由。
1)如果優(yōu)化的代碼已經正常工作,優(yōu)化后可能會引入新的bug;
2)優(yōu)化代碼趨向于使代碼更難理解和維護;
3)在一個平臺上優(yōu)化的代碼,在另一個平臺上可能更糟;
4)花費很多時間在代碼的優(yōu)化上,提高了很少的性能,卻導致了晦澀的代碼。確實,在優(yōu)化前,我們必須認真的考慮是否值得去優(yōu)化。
1.3 調優(yōu)的步驟
一般我們提高應用程序的性能劃分為以下幾個步驟:
1)明確應用程序的性能指標,怎樣才符合期望的性能需求;
2)在目標平臺進行測試;
3)如果性能已經達到性能指標,Stop;
4)查找性能瓶頸;
5)修改性能瓶頸;
6)返回到第2步。
二 JDK調優(yōu)
2.1 選擇合適的JDK版本
不同版本的JDK,甚至不同廠家的JDK可能都存在著很大的差異,對于性能優(yōu)化的程度不同。一般來說,盡可能選擇最新發(fā)布的穩(wěn)定的JDK版本。最新的穩(wěn)定的JDK版本相對以前的JDK版本都會做一些bug的修改和性能的優(yōu)化工作。
2.2 垃圾收集Java堆的優(yōu)化
垃圾收集就是自動釋放不再被程序所使用的對象的過程。當一個對象不再被程序所引用時,它所引用的堆空間可以被回收,以便被后續(xù)的新對象所使用。垃圾收集 器必須能夠斷定哪些對象是不再被引用的,并且能夠把它們所占據的堆空間釋放出來。如果對象不再被使用,但還有被程序所引用,這時是不能被垃圾收集器所回收 的,此時就是所謂的“內存泄漏”。監(jiān)控應用程序是否發(fā)生了內存泄漏,有一個非常優(yōu)秀的監(jiān)控工具推薦給大家——Quest公司的JProbe工具,使用它來 觀察程序運行期的內存變化,并可產生內存快照,從而分析并定位內存泄漏的確切位置,可以精確定位到源碼內。這個工具的使用我在后續(xù)的章節(jié)中還會做具體介 紹。
Java堆是指在程序運行時分配給對象生存的空間。通過-mx/-Xmx和-ms/-Xms來設置起始堆的大小和最大堆的大小。根據自己JDK的版本和廠家決定使用-mx和-ms或-Xmx和-Xms。Java堆大小決定了垃圾回收的頻度和速度,Java堆越大,垃圾回收的頻度越 低,速度越慢。同理,Java堆越小,垃圾回收的頻度越高,速度越快。要想設置比較理想的參數,還是需要了解一些基礎知識的。Java堆的最大值不能太大,這樣會造成系統內存被頻繁的交換和分頁。所以最大內存必須低于物理內存減去其他應用程序和進程需要的內存。而且堆設置的太 大,造成垃圾回收的時間過長,這樣將得不償失,極大的影響程序的性能。以下是一些經常使用的參數設置:
1)設置-Xms等于-XmX的值;
2)估計內存中存活對象所占的空間的大小,設置-Xms等于此值,-Xmx四倍于此值;
3)設置-Xms等于-Xmx的1/2大小;
4)設置-Xms介于-Xmx的1/10到1/4之間;
5)使用默認的設置。
大家需要根據自己的運行程序的具體使用場景,來確定最適合自己的參數設置。除了-Xms和-Xmx兩個最重要的參數外,還有很多可能會用到的參數,這些參數通常強烈的依賴于垃圾收集的算法,所以可能因為JDK的版本和廠家而有所 不同。但這些參數一般在Web開發(fā)中用的比較少,我就不做詳細介紹了。在實際的應用中注意設置-Xms和-Xmx使其盡可能的優(yōu)化應用程序就行了。對于性 能要求很高的程序,就需要自己再多研究研究Java虛擬機和垃圾收集算法的機制了。可以看看曹曉鋼翻譯的《深入Java虛擬機》一書。
第四篇:Oracle性能調優(yōu)實踐中的幾點心得
Oracle性能調優(yōu)實踐中的幾點心得
很多的時侯,做Oracle DBA的我們,當應用管理員向我們通告現在應用很慢、數據庫很慢的時侯,我們到數據庫時做幾個示例的Select也發(fā)現同樣的問題時,有些時侯我們會無從下手,因為我們認為數據庫的各種命種率都是滿足Oracle文檔的建議。實際上如今的優(yōu)化己經向優(yōu)化等待(waits)轉型了,實際中性能優(yōu)化最根本的出現點也都集中在IO,這是影響性能最主要的方面,由系統中的等待去發(fā)現Oracle庫中的不足、操作系統某些資源利用的不合理是一個比較好的辦法,下面把我的一點實踐經驗與大家分享一下,本文測重于Unix環(huán)境。
一、通過操作系統的一些工具檢查系統的狀態(tài),比如CPU、內存、交換、磁盤的利用率,根據經驗或與系統正常時的狀態(tài)相比對,有時系統表面上看起來看空閑這也可能不是一個正常的狀態(tài),因為cpu可能正等待IO的完成。除此之外我們還應觀注那些占用系統資源(cpu、內存)的進程。
1、如何檢查操作系統是否存在IO的問題?使用的工具有sar,這是一個比較通用的工具。Rp1#Sar-u 2 10 即每隔2秒檢察一次,共執(zhí)行20次,當然這些都由你決定了。
示例返回:
HP-UX hpn2 B.11.00 U 9000/800 08/05/03 18:26:32 %usr %sys %wio %idle 18:26:34 80 9 12 0 18:26:36 78 11 11 0 18:26:38 78 9 13 1 18:26:40 81 10 9 1 18:26:42 75 10 14 0 18:26:44 76 8 15 0 18:26:46 80 9 10 1 18:26:48 78 11 11 0 18:26:50 79 10 10 0 18:26:52 81 10 9 0 Average 79 10 11 0 其中的%usr指的是用戶進程使用的cpu資源的百分比,%sys指的是系統資源使用cpu資源的百分比,%wio指的是等待io完成的百分比,這是值得我們觀注的一項,%idle即空閑的百分比。如果wio列的值很大,如在35%以上,說明你的系統的IO存在瓶頸,你的CPU花費了很大的時間去等待IO的完成。Idle很小說明系統CPU很忙。像我的這個示例,可以看到wio平均值為11說明io沒什么特別的問題,而我的idle值為零,說明我的cpu已經滿負荷運行了。當你的系統存在IO的問題,可以從以下幾個方面解決
♀聯系相應的操作系統的技術支持對這方面進行優(yōu)化,比如hp-ux在劃定卷組時的條帶化等方面。
♀查找Oracle中不合理的sql語句,對其進行優(yōu)化 ♀對Oracle中訪問量頻繁的表除合理建索引外,再就是把這些表分表空間存放以免訪問上產生熱點,再有就是對表合理分區(qū)。
2、關注一下內存。
常用的工具便是vmstat,對于hp-unix來說可以用glance,Aix來說可以用topas,當你發(fā)現vmstat中pi列非零,memory中的free列的值很小,glance,topas中內存的利用率多于80%時,這時說明你的內存方面應該調節(jié)一下了,方法大體有以下幾項。
♀劃給Oracle使用的內存不要超過系統內存的1/2,一般保在系統內存的40%為益。
♀為系統增加內存
♀如果你的連接特別多,可以使用MTS的方式
♀打全補丁,防止內存漏洞。
3、如何找到點用系用資源特別大的Oracle的session及其執(zhí)行的語句。Hp-unix可以用glance,top IBM AIX可以用topas 些外可以使用ps的命令。
通過這些程序我們可以找到點用系統資源特別大的這些進程的進程號,我們就可以通過以下的sql語句發(fā)現這個pid正在執(zhí)行哪個sql,這個sql最好在pl/sql developer,toad等軟件中執(zhí)行, 把<>中的spid換成你的spid就可以了。SELECT a.username, a.machine, a.program, a.sid, a.serial#, a.status, c.piece, c.sql_text FROM v$session a, v$process b, v$sqltext c WHERE b.spid=
提示:我在做優(yōu)化sql時,經常碰到使用in的語句,這時我們一定要用exists把它給換掉,因為Oracle在處理In時是按Or的方式做的,即使使用了索引也會很慢。比如:
SELECT col1,col2,col3 FROM table1 a WHERE a.col1 not in(SELECT col1 FROM table2)可以換成:
SELECT col1,col2,col3 FROM table1 a WHERE not exists(SELECT 'x' FROM table2 b WHERE a.col1=b.col1)
4、另一個有用的腳本:查找前十條性能差的sql.SELECT * FROM(SELECT PARSING_USER_ID EXECUTIONS, SORTS, COMMAND_TYPE, DISK_READS, sql_text FROM v$sqlarea ORDER BY disk_reads DESC)WHERE ROWNUM<10;
二、迅速發(fā)現Oracle Server的性能問題的成因,我們可以求助于v$session_wait這個視圖,看系統的這些session在等什么,使用了多少的IO。以下是我提供的參考腳本: 腳本說明:查看占io較大的正在運行的session SELECT se.sid, se.serial#, pr.SPID, se.username, se.status, se.terminal, se.program, se.MODULE, se.sql_address, st.event, st.p1text, si.physical_reads, si.block_changes FROM v$session se, v$session_wait st, v$sess_io si, v$process pr WHERE st.sid=se.sid AND st.sid=si.sid AND se.PADDR=pr.ADDR AND se.sid>6 AND st.wait_time=0 AND st.event NOT LIKE '%SQL%' ORDER BY physical_reads DESC 對檢索出的結果的幾點說明:
1、我是按每個正在等待的session已經發(fā)生的物理讀排的序,因為它與實際的IO相關。
2、你可以看一下這些等待的進程都在忙什么,語句是否合理? Select sql_address from v$session where sid=
你也以用alter system kill session 'sid,serial#';把這個session殺掉。
3、應觀注一下event這列,這是我們調優(yōu)的關鍵一列,下面對常出現的event做以簡要的說明: a、buffer busy waits,free buffer waits 這兩個參數所標識是dbwr是否夠用的問題,與IO很大相關的,當v$session_wait中的
free buffer wait的條目很小或沒有的時侯,說明你的系統的dbwr進程決對夠用,不用調整; free buffer wait的條目很多,你的系統感覺起來一定很慢,這時說明你的dbwr已經不夠用了,它產生的wio已經成為你的數據庫性能的瓶頸,這時的解決辦法如下: a.1增加寫進程,同時要調整db_block_lru_latches參數
示例:修改或添加如下兩個參數 db_writer_processes=4 db_block_lru_latches=8 a.2開異步IO,IBM這方面簡單得多,hp則麻煩一些,可以與Hp工程師聯系。
b、db file sequential read,指的是順序讀,即全表掃描,這也是我們應該盡量減少的部分,解決方法就是使用索引、sql調優(yōu),同時可以增大db_file_multiblock_read_count這個參數。
c、db file scattered read,這個參數指的是通過索引來讀取,同樣可以通過增加db_file_multiblock_read_count這個參數來提高性能。d、latch free,與栓相關的了,需要專門調節(jié)。e、其他參數可以不特別觀注。
第五篇:iOS Core Animation 性能調優(yōu) 學習筆記
iOS Core Animation 性能調優(yōu) 學習筆
記
高效繪圖
一些關鍵詞
軟件繪圖
上下文:指代軟件繪圖(意即:不由GPU協助 的繪圖)軟件繪圖通常是由Core Graphics框架完成來完成
繪制速度 OpenGL>Core Animation>Core Graphics 消耗可觀的內存
CALayer 只需要一些與自己相關 的內存:只有它的寄宿圖會消耗一定的內存空間。即使直接賦給 contents 屬性一 張圖片,也不需要增加額外的照片存儲大小。如果相同的一張圖片被多個圖層作 為 contents 屬性,那么他們將會共用同一塊內存,而不是復制內存塊。
如果你實現了
-drawLayer:inContext:-drawRect:
這兩個方法中的任意一個方法,圖層就創(chuàng)建了了一個繪制上下文,這個上下文需要的大小的內存可從這個算式得出:圖層寬*圖 層高*4字節(jié),寬高的單位均為像素。對于一個在Retina iPad上的全屏圖層來說,這 個內存量就是 2048*1526*4字節(jié),相當于12MB內存,圖層每次重繪的時候都需要 重新抹掉內存然后重新分配。
你應該避免重繪你的視圖。提高繪制性能 的秘訣就在于盡量避免去繪制。矢量圖形
我們用Core Graphics來繪圖的一個通常原因就是只是用圖片或是圖層效果不能 輕易地繪制出矢量圖形。矢量繪圖包含一下這些:斜線或曲線漸變 Core Animation為這些圖形類型的繪制提供了專門的類,并給他們提供硬件支持(第六章『專有圖層』有詳細提到)。CAShapeLayer 可以繪制多邊形,直線和 曲線。CATextLayer 可以繪制文本。CAGradientLayer 用來繪制漸變。這些總 體上都比Core Graphics更快,同時他們也避免了創(chuàng)造一個寄宿圖。臟矩形,Mac OS和iOS設備將會把屏幕區(qū)分為需要重繪的區(qū)域和 不需要重繪的區(qū)域。那些需要重繪的部分被稱作『臟區(qū)域』。在實際應用中,鑒于 非矩形區(qū)域邊界裁剪和混合的復雜性,通常會區(qū)分出包含指定視圖的矩形位置,而 這個位置就是『臟矩形』。但是Core Animation通常并不了 解你的自定義繪圖代碼,它也不能自己計算出臟區(qū)域的位置。然而,你的確可以提 供這些信息。當你檢測到指定視圖或圖層的指定部分需要被重繪,你直接調用(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return [self.imagePaths count];} imageRect.size.height)/2;
//draw tile
UIGraphicsPushContext(ctx);
[tileImage drawInRect:imageRect];
UIGraphicsPopContext();}
@end
需要解釋幾點:
CATiledLayer的tileSize屬性單位是像素,而不是點,所以為了保證瓦片和表格尺寸一致,需要乘以屏幕比例因子。
在-drawLayer:inContext:方法中,我們需要知道圖層屬于哪一個indexPath以加載正確的圖片。這里我們利用了CALayer的KVC來存儲和檢索任意的值,將圖層和索引打標簽。
分辨率交換
視網膜分辨率(根據蘋果市場定義)代表了人的肉眼在正常視角距離能夠分辨的最小像素尺寸。但是這只能應用于靜態(tài)像素。當觀察一個移動圖片時,你的眼睛就會對細節(jié)不敏感,于是一個低分辨率的圖片和視網膜質量的圖片沒什么區(qū)別了。+
如果需要快速加載和顯示移動大圖,簡單的辦法就是欺騙人眼,在移動傳送器的時候顯示一個小圖(或者低分辨率),然后當停止的時候再換成大圖。這意味著我們需要對每張圖片存儲兩份不同分辨率的副本,但是幸運的是,由于需要同時支持Retina和非Retina設備,本來這就是普遍要做到的。
如果從遠程源或者用戶的相冊加載沒有可用的低分辨率版本圖片,那就可以動態(tài)將大圖繪制到較小的CGContext,然后存儲到某處以備復用。
為了做到圖片交換,我們需要利用UIScrollView的一些實現UIScrollViewDelegate協議的委托方法(和其他類似于UITableView和UICollectionView基于滾動視圖的控件一樣):
(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;
你可以使用這幾個方法來檢測傳送器是否停止?jié)L動,然后加載高分辨率的圖片。只要高分辨率圖片和低分辨率圖片尺寸顏色保持一致,你會很難察覺到替換的過程(確保在同一臺機器使用相同的圖像程序或者腳本生成這些圖片)。
緩存 如果有很多張圖片要顯示,最好不要提前把所有都加載進來,而是應該當移出屏幕之后立刻銷毀。通過選擇性的緩存,你就可以避免來回滾動時圖片重復性的加載了。
+imageNamed:方法
之前我們提到使用[UIImage imageNamed:]加載圖片有個好處在于可以立刻解壓圖片而不用等到繪制的時候。但是[UIImage imageNamed:]方法有另一個非常顯著的好處:它在內存中自動緩存了解壓后的圖片,即使你自己沒有保留對它的任何引用。
對于iOS應用那些主要的圖片(例如圖標,按鈕和背景圖片),使用[UIImage imageNamed:]加載圖片是最簡單最有效的方式。在nib文件中引用的圖片同樣也是這個機制,所以你很多時候都在隱式的使用它。
但是[UIImage imageNamed:]并不適用任何情況。它為用戶界面做了優(yōu)化,但是并不是對應用程序需要顯示的所有類型的圖片都適用。有些時候你還是要實現自己的緩存機制,原因如下:
-[UIImage imageNamed:]方法僅僅適用于在應用程序資源束目錄下的圖片,但是大多數應用的許多圖片都要從網絡或者是用戶的相機中獲取,所以[UIImage imageNamed:]就沒法用了。
-[UIImage imageNamed:]緩存用來存儲應用界面的圖片(按鈕,背景等等)。如果對照片這種大圖也用這種緩存,那么iOS系統就很可能會移除這些圖片來節(jié)省內存。那么在切換頁面時性能就會下降,因為這些圖片都需要重新加載。對傳送器的圖片使用一個單獨的緩存機制就可以把它和應用圖片的生命周期解耦。
-[UIImage imageNamed:]緩存機制并不是公開的,所以你不能很好地控制它。例如,你沒法做到檢測圖片是否在加載之前就做了緩存,不能夠設置緩存大小,當圖片沒用的時候也不能把它從緩存中移除。
自定義緩存
構建一個所謂的緩存系統非常困難。菲爾 卡爾頓曾經說過:“在計算機科學中只有兩件難事:緩存和命名”。
如果要寫自己的圖片緩存的話,那該如何實現呢?讓我們來看看要涉及哪些方面:
-選擇一個合適的緩存鍵如果生成和加載數據的代價很大,你可能想當第一次需要用到的時候再去加載和緩存。提前加載的邏輯是應用內在就有的,但是在我們的例子中,這也非常好實現,因為對于一個給定的位置和滾動方向,我們就可以精確地判斷出哪一張圖片將會出現。
-緩存失效當內存不夠的時候,如何判斷哪些緩存需要清空呢?這就需要到你寫一個合適的算法了。幸運的是,對緩存回收的問題,蘋果提供了一個叫做NSCache通用的解決方案
NSCache
NSCache和NSDictionary類似。你可以通過-setObject:forKey:和-object:forKey:方法分別來插入,檢索。和字典不同的是,NSCache在系統低內存的時候自動丟棄存儲的對象。
NSCache用來判斷何時丟棄對象的算法并沒有在文檔中給出,但是你可以使用-setCountLimit:方法設置緩存大小,以及-setObject:forKey:cost:來對每個存儲的對象指定消耗的值來提供一些暗示。
指定消耗數值可以用來指定相對的重建成本。如果對大圖指定一個大的消耗值,那么緩存就知道這些物體的存儲更加昂貴,于是當有大的性能問題的時候才會丟棄這些物體。你也可以用-setTotalCostLimit:方法來指定全體緩存的尺寸。
NSCache是一個普遍的緩存解決方案,我們創(chuàng)建一個比傳送器案例更好的自定義的緩存類。(例如,我們可以基于不同的緩存圖片索引和當前中間索引來判斷哪些圖片需要首先被釋放)。但是NSCache對我們當前的緩存需求來說已經足夠了;沒必要過早做優(yōu)化。
#import “ViewController.h”
@interface ViewController()
@property(nonatomic, copy)NSArray *imagePaths;@property(nonatomic, weak)IBOutlet UICollectionView *collectionView;
@end
@implementation ViewController
-(void)viewDidLoad {
//set up data
self.imagePaths = [[NSBundle mainBundle] pathsForResourcesOfType:@“png” ?inDirectory:@“Vacation Photos”];
//register cell class
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@“Cell”];}(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
//dequeue cell
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@“Cell” forIndexPath:indexPath];
//add imnc630.comage view
UIImageView *imageView = [cell.contentView.subviews lastObject];
if(!imageView){
imageView = [[UIImageView alloc] initWithFrame:cell.contentView.bounds];
imageView.contentMode = UIViewContentModeScaleAspectFit;
[cell.contentView addSubview:imageView];
}
//set or load image for this index
imageView.image = [self loadImageAtIndex:indexPath.item];
//preload image for previous and next index
if(indexPath.item < [self.imagePaths count]1];}
return cell;}
@end
果然效果更好了!當滾動的時候雖然還有一些圖片進入的延遲,但是已經非常罕見了。緩存意味著我們做了更少的加載。這里提前加載邏輯非常粗暴,其實可以把滑動速度和方向也考慮進來,但這已經比之前沒做緩存的版本好很多了。