04-基礎(chǔ)增強(qiáng)-第4天(java高級(jí)特性增強(qiáng))-講義_第1頁(yè)
04-基礎(chǔ)增強(qiáng)-第4天(java高級(jí)特性增強(qiáng))-講義_第2頁(yè)
04-基礎(chǔ)增強(qiáng)-第4天(java高級(jí)特性增強(qiáng))-講義_第3頁(yè)
04-基礎(chǔ)增強(qiáng)-第4天(java高級(jí)特性增強(qiáng))-講義_第4頁(yè)
04-基礎(chǔ)增強(qiáng)-第4天(java高級(jí)特性增強(qiáng))-講義_第5頁(yè)
已閱讀5頁(yè),還剩53頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

2、掌握并發(fā)包下的隊(duì)列5、掌握反射和動(dòng)態(tài)代理.1.java多線程基本知識(shí).1.1.進(jìn)程介紹專門負(fù)責(zé)當(dāng)前這個(gè)程序的運(yùn)行。會(huì)相互的影響。我們把每個(gè)獨(dú)立應(yīng)用程序在內(nèi)存的獨(dú)立空間稱為當(dāng)前應(yīng)用程序運(yùn)行的一個(gè)進(jìn)調(diào)度當(dāng)前程序中的所有運(yùn)行細(xì)節(jié)。.1.2.線程介紹它們都位于當(dāng)前QQ這個(gè)軟件運(yùn)行時(shí)所分配的內(nèi)容的獨(dú)立空間中。成多個(gè)運(yùn)行區(qū)域,每個(gè)獨(dú)立的小區(qū)域(小單元)稱為一個(gè)線程。線程:它是位于進(jìn)程中,負(fù)責(zé)當(dāng)前進(jìn)程中的某個(gè)具備獨(dú)立運(yùn)行資格的空間。程。.1.3.多線程介紹有線程。真正可以完成程序運(yùn)行和功能的實(shí)現(xiàn)靠的是進(jìn)程中的線程。多線程的目的:提高程序的運(yùn)行效率。.1.4.多線程運(yùn)行的原理行程序的過(guò)程中某個(gè)時(shí)刻點(diǎn)上,它其實(shí)只能運(yùn)行一個(gè)程序。而不是多個(gè)程序。而Cbn它可以在多個(gè)程序之間進(jìn)行高速的切換。而切換頻率和速度太快,導(dǎo)致人的肉看看不到。但不能無(wú)限制的開線程。.1.5.實(shí)現(xiàn)線程的兩種方式SRunnable的類.2.1.synchronized代碼塊中放操作共享數(shù)據(jù)的代碼。}有兩種情況:T)獲取鎖的線程執(zhí)行完了該代碼塊,然后線程釋放對(duì)鎖的占有;2)線程執(zhí)行發(fā)生異常,此時(shí)JVM會(huì)讓線程自動(dòng)釋放鎖。如果這個(gè)獲取鎖的線程由于要等待IO或者其他原因(比如調(diào)用sleep方法)被阻塞了,但是又沒有釋放鎖,其他線程便只能干巴巴地等待,試想一下,這多么影響程序執(zhí)行效率。因此就需要有一種機(jī)制可以不讓等待的線程一直無(wú)期限地等待下去(比如只等待一定的時(shí)間或者能夠響應(yīng)中斷),通過(guò)Lock就可以辦到。突現(xiàn)象,但是讀操作和讀操作不會(huì)發(fā)生沖突現(xiàn)象。nchronizedzed2.2lockLock是一個(gè)類,通過(guò)這個(gè)類可以實(shí)現(xiàn)同步訪問;2)Lock和synchronized有一點(diǎn)非常大的不同,采用synchronized不需要用戶去手動(dòng)釋鎖,當(dāng)synchronized方法或者synchronized代碼塊執(zhí)行完之后,系統(tǒng)會(huì)自動(dòng)讓線程釋放對(duì)鎖的占用;而Lock則必須要用戶去手動(dòng)釋放鎖,如果沒有主動(dòng)釋放鎖,就有可能導(dǎo)致出現(xiàn)?java.util.concurrent.locks包下常用的類Lock明的就是Lock,通過(guò)查看Lock的源碼可知,Lock是一個(gè)接口:publicpublicinterfaceLock{voidlock();voidlockInterruptibly()throwsInterruptedException;booleantryLock();booleantryLock(longtime,TimeUnitunit)throwsInterruptedException;voidunlock();}lyunLock()方法是用來(lái)釋放鎖的。ReadWriteLocklock()方法是平常使用得最多的一個(gè)方法,就是用來(lái)獲取鎖。如果鎖已被其他線程獲取,由于在前面講到如果采用Lock,必須主動(dòng)去釋放鎖,并且在發(fā)生異常時(shí),不會(huì)自動(dòng)釋塊中進(jìn)行,以保證鎖一定被被釋放,防止死鎖的發(fā)生。tryLock()方法是有返回值的,它表示用來(lái)嘗試獲取鎖,如果獲取成功,則返回true,如果獲取失敗(即鎖已被其他線程獲取),則返回false,也就說(shuō)這個(gè)方法無(wú)論如何都會(huì)立即返回。在拿不到鎖時(shí)不會(huì)一直在那等待。tryLock(longtime,TimeUnitunit)方法和tryLock()方法是類似的,只不過(guò)區(qū)別在于這個(gè)方法在拿不到鎖時(shí)會(huì)等待一定的時(shí)間,在時(shí)間期限之內(nèi)如果還拿不到鎖,就返回false。如果如果一開始拿到鎖或者在等待期間內(nèi)拿到了鎖,則返回true。lockInterruptibly()方法比較特殊,當(dāng)通過(guò)這個(gè)方法去獲取鎖時(shí),如果線程正在等待獲取鎖,則這個(gè)線程能夠響應(yīng)中斷,即中斷線程的等待狀態(tài)。也就使說(shuō),當(dāng)兩個(gè)線程同時(shí)通過(guò)注意,當(dāng)一個(gè)線程獲取了鎖之后,是不會(huì)被interrupt()方法中斷的。因此當(dāng)通過(guò)lockInterruptibly()方法獲取某個(gè)鎖時(shí),如果不能獲取到,只有進(jìn)行等待的情況下,是可以響應(yīng)中斷的。而用synchronized修飾的話,當(dāng)一個(gè)線程處于等待某個(gè)鎖的狀態(tài),是無(wú)法被中斷的,只有一直等待下去。ReentrantLock“可重入鎖”。ReadWriteLock也是一個(gè)接口,在它里面只定義了兩個(gè)方法:publicpublicinterfaceReadWriteLock{/***Returnsthelockusedforreading.**@returnthelockusedforreading.kreadLock/***Returnsthelockusedforwriting.**@returnthelockusedforwriting.LockwriteLock();}來(lái)分配給線程,從而使得多個(gè)線程可以同時(shí)進(jìn)行讀操作。下面的ReentrantReadWriteLock實(shí)ReentrantReadWriteLockReentrantReadWriteLock里面提供了很多豐富的方法,不過(guò)最主要的有兩個(gè)方法:ReadWriteLock果不過(guò)要注意的是,如果有一個(gè)線程已經(jīng)占用了讀鎖,則此時(shí)其他線程如果要申請(qǐng)寫鎖,則申請(qǐng)寫鎖的線程會(huì)一直等待釋放讀鎖。程會(huì)一直等待釋放寫鎖。Lock和synchronized的選擇LocksynchronizedJavasynchronized言而Lock在發(fā)生異常時(shí),如果沒有主動(dòng)通過(guò)unLock()去釋放鎖,則很可能造成死鎖現(xiàn)象,因等待的線程會(huì)一直等待下去,不能夠響應(yīng)中斷;4)通過(guò)Lock可以知道有沒有成功獲取鎖,而synchronized卻無(wú)法辦到。5)Lock可以提高多個(gè)線程進(jìn)行讀操作的效率。時(shí)(即有大量線程同時(shí)競(jìng)爭(zhēng)),此時(shí)Lock的性能要遠(yuǎn)遠(yuǎn)優(yōu)于synchronized。所以說(shuō),在具體使用時(shí)要根據(jù)適當(dāng)情況選擇。.1.java并發(fā)包介紹JDK5.0以后的版本都引入了高級(jí)并發(fā)特性,大多數(shù)的特性在java.util.concurrent包中,發(fā)應(yīng)用程序。主要包含原子量、并發(fā)集合、同步器、可重入鎖,并對(duì)線程池的構(gòu)造提供了強(qiáng)力的支持。線程池r在構(gòu)造函數(shù)中的參數(shù)4是線程池的大小,你可以隨意設(shè)置,也可以和cpu的數(shù)量保持一NumsRuntimegetRuntimeavailableProcessors5、SingleThreadScheduledPool:只有一個(gè)線程,用來(lái)調(diào)度執(zhí)行將來(lái)的任務(wù),代碼:Executors.newSingleThreadScheduledExecutor()線程池的使用提交Runnable,任務(wù)完成后Future對(duì)象返回null提交Callable,該方法返回一個(gè)Future實(shí)例表示任務(wù)的狀態(tài).2.java并發(fā)包消息隊(duì)列及在開源軟件中的應(yīng)用BlockingQueue也是java.util.concurrent下的主要用來(lái)控制線程同步的工具。插插入:2)offer(anObject):表示如果可能的話,將anObject加到BlockingQueue里,即如果putanObjectanObjectBlockingQueue果BlockQueue沒有空間,則調(diào)用此方法的線程被阻斷直到BlockingQueue里面有空間再繼續(xù).4)poll(time):取走BlockingQueue里排在首位的對(duì)象,若不能立即取出,則可以等timenull5)take():取走BlockingQueue里排在首位的對(duì)象,若BlockingQueue為空,阻斷進(jìn)入等待狀態(tài)直到Blocking有新的對(duì)象被加入為止他intremainingCapacity();返回隊(duì)列剩余的容量,在隊(duì)列插入和獲取的時(shí)候,不要瞎搞,數(shù)據(jù)可能不準(zhǔn)booleanremove(Objecto);從隊(duì)列移除元素,如果存在,即移除一個(gè)或者更多,隊(duì)列改publicbooleancontains(Objecto);查看隊(duì)列是否存在這個(gè)元素,存在返回trueintdrainTo(Collection<?superE>c);傳入的集合中的元素,如果在隊(duì)列中存在,那么將隊(duì)列中的元素移動(dòng)到集合中intdrainTo(Collection<?superE>c,intmaxElements);和上面方法的區(qū)別在于,制定了移動(dòng)的數(shù)量BlockingQueue有四個(gè)具體的實(shí)現(xiàn)類,常用的兩種實(shí)現(xiàn)類為:1、ArrayBlockingQueue:一個(gè)由數(shù)組支持的有界阻塞隊(duì)列,規(guī)定大小的BlockingQueue,其構(gòu)造函數(shù)必須帶一個(gè)int參數(shù)來(lái)指明其大小.其所含的對(duì)象是以FIFO(先入先出)順序排序的。2、LinkedBlockingQueue:大小不定的BlockingQueue,若其構(gòu)造函數(shù)帶一個(gè)規(guī)定大小的參數(shù),生成的BlockingQueue有大小限制,若不帶大小參數(shù),所生成的BlockingQueue的大小由IntegerMAXVALUE含的對(duì)象是以FIFO(先入先出)順序排序的。LinkedBlockingQueue可以指定容量,也可以不指定,不指定的話,默認(rèn)最大是takeput隊(duì)列成員被消費(fèi),take方法在隊(duì)列空的時(shí)候會(huì)阻塞,直到有隊(duì)列成員被放進(jìn)來(lái)。LinkedBlockingQueue和ArrayBlockingQueue比較起來(lái),它們背后所用的數(shù)據(jù)結(jié)構(gòu)不一樣,導(dǎo)致LinkedBlockingQueue的數(shù)據(jù)吞吐量要大于ArrayBlockingQueue,但在線程數(shù)量很大時(shí)其性能的yBlockingQueue代碼消息中間件(MOM)的API,用于在兩個(gè)應(yīng)用程序之間,或分布式系統(tǒng)中發(fā)送消息,進(jìn)行異JMS是一種與廠商無(wú)關(guān)的API,用來(lái)訪問消息收發(fā)系統(tǒng)消息。它類似于JDBC(JavaJMSMQSeries、BEA的WeblogicJMSservice和Progress的SonicMQ,這只是幾個(gè)例子。JMS使您能夠通過(guò)消息收發(fā)服務(wù)(有時(shí)稱為消息中介程序或路由器)從一個(gè)JMS客戶機(jī)向另一個(gè)JMS客戶機(jī)發(fā)送消息。消息是JMS中的一種類型對(duì)象,由兩部分組成:報(bào)頭和消息主體。報(bào)頭由路由信息以及有關(guān)該消息的元數(shù)據(jù)組成。消息主體則攜帶著應(yīng)用程序的數(shù)據(jù)或有效負(fù)載。根據(jù)有效負(fù)載的類型來(lái)劃分,可以將消息分為幾種類型,它們分別攜帶:簡(jiǎn)單文本(TextMessage)、可序列化的對(duì)象(ObjectMessage)、屬性集合(MapMessage)、字節(jié)流BytesMessage)、原始值流(StreamMessage),還有無(wú)有效負(fù)載的消息(Message)。.2.JMS規(guī)范.2.1.專業(yè)技術(shù)規(guī)范JMS(JavaMessagingService)是Java平臺(tái)上有關(guān)面向消息中間件(MOM)的技術(shù)規(guī)范,它便于消息系統(tǒng)中的Java應(yīng)用程序進(jìn)行消息交換,并且通過(guò)提供標(biāo)準(zhǔn)的產(chǎn)生、發(fā)送、接收消息的.2.2.體系架構(gòu)JMS由以下元素組成。Java面向消息中間件的適配器。JMS客戶:生產(chǎn)或消費(fèi)基于消息的Java的應(yīng)用程序或?qū)ο蟆MS生產(chǎn)者:創(chuàng)建并發(fā)送消息的JMS客戶。JMSJMS。JMS消息:包括可以在JMS客戶之間傳遞的數(shù)據(jù)的對(duì)象JMS隊(duì)列:一個(gè)容納那些被發(fā)送的等待閱讀的消息的區(qū)域。與隊(duì)列名字所暗示的意思不同,JMS主題:一種支持發(fā)送消息給多個(gè)訂閱者的機(jī)制。.2.3.Java消息服務(wù)應(yīng)用程序結(jié)構(gòu)支持兩種模型在點(diǎn)對(duì)點(diǎn)或隊(duì)列模型下,一個(gè)生產(chǎn)者向一個(gè)特定的隊(duì)列發(fā)布消息,一個(gè)消費(fèi)者從該隊(duì)列中讀取消息。這里,生產(chǎn)者知道消費(fèi)者的隊(duì)列,并直接將消息發(fā)送到消費(fèi)者的隊(duì)列。只有一個(gè)消費(fèi)者將獲得消息生產(chǎn)者不需要在接收者消費(fèi)該消息期間處于運(yùn)行狀態(tài),接收者也同樣不需要在消息發(fā)送時(shí)處于運(yùn)行狀態(tài)。每一個(gè)成功處理的消息都由接收者簽收2、發(fā)布者/訂閱者模型發(fā)布者/訂閱者模型支持向一個(gè)特定的消息主題發(fā)布消息。0或多個(gè)訂閱者可能對(duì)接收來(lái)自多個(gè)消費(fèi)者可以獲得消息在發(fā)布者和訂閱者之間存在時(shí)間依賴性。發(fā)布者需要建立一個(gè)訂閱(subscription),以便客戶能夠訂閱。訂閱者必須保持持續(xù)的活動(dòng)狀態(tài)以接收消息,除非訂閱者建立了持久的訂閱。在那種情況下,在訂閱者未連接時(shí)發(fā)布的消息將在訂閱者重新連接時(shí)重新發(fā)布。JavaJMS方式。同一組Java類可以通過(guò)JNDI中關(guān)于提供者的信息,連接不同的JMS提供者。這一組類首先使用一個(gè)連接工廠以連接到隊(duì)列或主題,然后發(fā)送或發(fā)布消息。在接收端,客戶接收或訂閱這些消息。.2.4.代碼演示apacheactivemqbinzipst<<transportConnectors><transportConnectorname="openwire"uri="tcp://localhost:61616"/><transportConnectorname="ssl"uri="ssl://localhost:61617"/><transportConnectorname="stomp"uri="stomp://localhost:61613"/><transportConnectoruri="http://localhost:8081"/><transportConnectoruri="udp://localhost:61618"/>apacheactivemqbinactivemqbatActiveMQ程序。3.運(yùn)行代碼括:ApacheActiveMQJBoss社區(qū)所研發(fā)的HornetQJoramGroupOpenJMS括:temsQ.1.java監(jiān)控工具使用.1.1.jconsolejconsole是一種集成了上面所有命令功能的可視化工具,可以分析jvm的內(nèi)存使用情況JDKbinjconsoleexeJconsole所有虛擬機(jī)進(jìn)程,不需要用戶使用jps來(lái)查詢了,雙擊其中一個(gè)進(jìn)程即可開始監(jiān)控。也可以“遠(yuǎn)程連接服務(wù)器,進(jìn)行遠(yuǎn)程虛擬機(jī)的監(jiān)控?!备攀鲰?yè)面顯示的是整個(gè)虛擬機(jī)主要運(yùn)行數(shù)據(jù)的概覽。.1.2.jvisualvmjconsole能類似,提供了一大堆的插件。.2.java內(nèi)存模型.2.1.內(nèi)存模型圖解Java虛擬機(jī)在執(zhí)行Java程序的過(guò)程中,會(huì)把它所管理的內(nèi)存劃分為若干個(gè)不同的數(shù)據(jù)如下圖是一個(gè)內(nèi)存模型的關(guān)系圖(詳情見圖:內(nèi)存劃分.png):如上圖所示,Java虛擬機(jī)運(yùn)行時(shí)數(shù)據(jù)區(qū)域被分為五個(gè)區(qū)域:堆(Heap)、棧(Stack)、本地方法棧(NativeStack)、方法區(qū)(MethodArea)、程序計(jì)數(shù)器(ProgramCountRegister)。.2.2.堆(Heap)JavaHeapJava域隨著聽說(shuō)線程安全的問題,就會(huì)很明確的知道JavaHeap是一塊共享的區(qū)域,操作共享區(qū)域的成與JavaHeap相關(guān)的還有Java的垃圾回收機(jī)制(GC),JavaHeap是垃圾回收器管理的主要區(qū)域。程序猿所熟悉的新生代、老生代、永久代的概念就是在堆里面,現(xiàn)在大多數(shù)的GC基本都采用了分代收集算法。如果再細(xì)致一點(diǎn),JavaHeap還有Eden空間,F(xiàn)romSurvivor空ToSurvivor間等。JavaHeap可以處于物理上不連續(xù)的內(nèi)存空間中,只要邏輯上是連續(xù)的即可。.2.3.棧(Stack)kJava模型,每個(gè)方法執(zhí)行時(shí)都會(huì)創(chuàng)建一個(gè)棧幀(StackFrame)用語(yǔ)存儲(chǔ)局部變量表、操作數(shù)棧、動(dòng)態(tài)鏈接、方法出口等信息。從下圖從可以看到,每個(gè)線程在執(zhí)行一個(gè)方法時(shí),都意味著有一個(gè)棧幀在當(dāng)前線程對(duì)應(yīng)的棧幀中入棧和出棧。圖中可以看到每一個(gè)棧幀中都有局部變量表。局部變量表存放了編譯期間的各種基本數(shù)據(jù)類.2.4.本地方法棧(NativeStack)本地方法棧(NativeStack)與Java虛擬機(jī)站(JavaStack)所發(fā)揮的作用非常相似,他們之間的區(qū)別在于虛擬機(jī)棧為虛擬機(jī)棧執(zhí)行java方法(也就是字節(jié)碼)服務(wù),而本地方法e.2.5.方法區(qū)(MethodArea)方法區(qū)(MethodArea)與堆(JavaHeap)一樣,是各個(gè)線程共享的內(nèi)存區(qū)域,它用于存儲(chǔ)虛擬機(jī)加載的類信息,常量,靜態(tài)變量,即時(shí)編譯器編譯后的代碼等數(shù)據(jù)。雖然Javap分析下Java虛擬機(jī)規(guī)范,之所以把方法區(qū)描述為堆的一個(gè)邏輯部分,應(yīng)該覺得她們都是存儲(chǔ)數(shù)據(jù)的角度出發(fā)的。一個(gè)存儲(chǔ)對(duì)象數(shù)據(jù)(堆),一個(gè)存儲(chǔ)靜態(tài)信息(方法區(qū))。在上文中,我們看到堆中有新生代、老生代、永久代的描述。為什么我們將新生代、老生代、永久代三個(gè)概念一起說(shuō),那是因?yàn)镠otSpot虛擬機(jī)的設(shè)計(jì)團(tuán)隊(duì)選擇把GC分代收集擴(kuò)Java堆一樣管理這部分內(nèi)存。簡(jiǎn)單點(diǎn)說(shuō)就是HotSpot虛擬機(jī)中內(nèi)存模型的分代,其中新生代在永久代的字符串常量池移出。 Java虛擬機(jī)棧(JavaStack)本地方法棧(NativeStack)堆(JavaHeap)方法區(qū).3.GC算法.3.1.標(biāo)記-清除算法(Mark-Sweep)1、標(biāo)記出所有需要回收的對(duì)象,在標(biāo)記完成后統(tǒng)一回收所有被標(biāo)記的對(duì)象2、在標(biāo)記完成后統(tǒng)一回收所有被標(biāo)記的對(duì)象缺點(diǎn):一個(gè)是效率問題,標(biāo)記和清除兩個(gè)過(guò)程的效率都不高;另一個(gè)是空間問題,標(biāo)記清除之后會(huì)產(chǎn)生大量不連續(xù)的內(nèi)存碎片,空間碎片太多可能會(huì)導(dǎo)致以后在程序運(yùn)行過(guò)程中需要分配較大對(duì)象時(shí),無(wú)法找到足夠的連續(xù)內(nèi)存而不得不提前觸發(fā)另一次垃圾收集動(dòng)作。.3.2.復(fù)制算法(Copying)每次只使用其中的一塊。2、當(dāng)這一塊的內(nèi)存用完了,就將還存活著的對(duì)象復(fù)制到另外一塊上面,然后再把已使用過(guò)的內(nèi)存空間一次清理掉。優(yōu)點(diǎn):這樣使得每次都是對(duì)整個(gè)半?yún)^(qū)進(jìn)行內(nèi)存回收,內(nèi)存分配時(shí)也就不用考慮內(nèi)存碎片等復(fù)雜情況,只要移動(dòng)堆頂指針,按順序分配內(nèi)存即可,實(shí)現(xiàn)簡(jiǎn)單,運(yùn)行高效。只是這種算法的代價(jià)是將內(nèi)存縮小為缺點(diǎn):復(fù)制收集算法在對(duì)象存活率較高時(shí)就要進(jìn)行較多的復(fù)制操作,效率將會(huì)變低.3.3.標(biāo)記-整理算法(Mark-Compact)2、讓所有存活的對(duì)象都向一端移動(dòng),然后直接清理掉端邊界以外的內(nèi)存.3.4.分代收集算法(GenerationalCollection)3、在新生代中,每次垃圾收集時(shí)都發(fā)現(xiàn)有大批對(duì)象死去,只有少量存活,那就選用復(fù)制算法,只需要付出少量存活對(duì)象的復(fù)制成本就可以完成收集。4、老年代中因?yàn)閷?duì)象存活率高、沒有額外空間對(duì)它進(jìn)行分配擔(dān)保,就必須使用“標(biāo)記—清理”或者“標(biāo)記—整理”算法來(lái)進(jìn)行回收。.4.垃圾回收器.4.1.Serial收集器:1、是一個(gè)單線程的收集器,“StopTheWorld”Client式下的虛擬機(jī)來(lái)說(shuō)是一個(gè)很好的選擇4、簡(jiǎn)單而高效.4.2.SerialOld收集器.4.3.ParNew收集器4、使用-XX:+UseConcMarkSweepGC選項(xiàng)后的默認(rèn)新生代收集器,也可以使用-XX:.4.4.ParallelScavenge收集器集器2、新生代收集器,復(fù)制算法,并行的多線程收集器3、目標(biāo)是達(dá)到一個(gè)可控制的吞吐量(Throughput)。4、吞吐量=運(yùn)行用戶代碼時(shí)間/(運(yùn)行用戶代碼時(shí)間+垃圾收集時(shí)間),虛擬機(jī)總共運(yùn)行了5、兩個(gè)參數(shù)用于精確控制吞吐量:XXMaxGCPauseMillisr代對(duì)象年齡6、并行(Parallel):指多條垃圾收集線程并行工作,但此時(shí)用戶線程仍然處于等待狀態(tài)。7、并發(fā)(Concurrent):指用戶線程與垃圾收集線程同時(shí)執(zhí)行(但不一定是并行的,可能會(huì)交替執(zhí)行),用戶CMS收集器一款優(yōu)秀的收集器1、以獲取最短回收停頓時(shí)間為目標(biāo)的收集器。站或者B/S系統(tǒng)的服務(wù)端上,重視服務(wù)的響應(yīng)速度,希望系統(tǒng)停頓時(shí)間最短的應(yīng)用3、基于“標(biāo)記—清除”算法實(shí)現(xiàn)的CMS器的內(nèi)存回收過(guò)程是與用戶線程一起并發(fā)執(zhí)行的標(biāo)記產(chǎn)生變動(dòng)的那一部分對(duì)象的標(biāo)記記錄,但遠(yuǎn)比并發(fā)標(biāo)記的時(shí)間短6、優(yōu)點(diǎn):并發(fā)收集、低停頓一款基于“標(biāo)記—清除”算法實(shí)現(xiàn)的收集器1、當(dāng)今收集器技術(shù)發(fā)展的最前沿成果之一存空間碎片可預(yù)測(cè)的停頓:能讓使用者明確指定在一個(gè)長(zhǎng)度為M毫秒的時(shí)間片段內(nèi),消耗在垃GCRoot達(dá)性分析,找出存活的對(duì)象,這階段耗時(shí)較長(zhǎng),但可與用戶程序并發(fā)執(zhí)行最終標(biāo)記:修正在并發(fā)標(biāo)記期間因用戶程序繼續(xù)運(yùn)作而導(dǎo)致標(biāo)記產(chǎn)生變動(dòng)的那一部分標(biāo)記記錄時(shí)間來(lái)制定回收計(jì)劃垃圾收集器參數(shù)總結(jié)-XX:+UseSerialGC:年輕串行(Serial),老年串行(SerialOld)-XX:+UseParNewGC:年輕并行(ParNew),老年串行(SerialOld)-XX:+UseConcMarkSweepGC:年輕并行(ParNew),老年串行(CMS),備份(SerialOld)-XX:+UseParallelGC:年輕并行吞吐(ParallelScavenge),老年串行(SerialOld)-XX:+UseParalledlOldGC:年輕并行吞吐(ParallelScavenge),老年并行吞吐(ParallelOld)U.5.JVM參數(shù)列表javajava-Xmx3550m-Xms3550m-Xmn2g-Xss128k-XX:NewRatio=4-XX:SurvivorRatio=4-XX:MaxPermSize=16m-XX:MaxTenuringThreshold=0XmxmM。Xmsm50m。此值可以設(shè)置與-Xmx相同,以避免每次垃圾回收完成后JVM重新分配內(nèi)存。gG整個(gè)堆大小=年輕代大小+年老代大小+持久代大小。持久代一般固定大小為64m,所以對(duì)系統(tǒng)性能影響較大,Sun官方推薦配置為整個(gè)-Xss128k:設(shè)置每個(gè)線程的堆棧大小。JDK5.0以后每個(gè)線程堆棧大小為1M,在相同物理內(nèi)存下,減小這個(gè)值能生成更多的線程。但是操作系統(tǒng)對(duì)一個(gè)進(jìn)程內(nèi)的線程數(shù)還是有限制的,不能無(wú)限生成,經(jīng)驗(yàn)值在3000~5000左右。XXNewRatio=4:設(shè)置年輕代(包括Eden和兩個(gè)Survivor區(qū))與年老代的比值(除去持久代)。urvivorvorXX:MaxPermSize=16m:設(shè)置持久代大小為16m。-XX:MaxTenuringThreshold=15:設(shè)置垃圾最大年齡。如果設(shè)置為0的話,則年輕代對(duì)象不經(jīng)過(guò)Survivor區(qū),直接進(jìn)入年老代。對(duì)于年老代比較多的應(yīng)用,可以提高效率。如果將此值設(shè)置為一個(gè)較大值,則年輕代對(duì)象會(huì)在Survivor區(qū)進(jìn)行多次復(fù)制,這樣可以增加對(duì)象再年輕代的存活時(shí)間,增加在年輕代即被回收的概論。收集器設(shè)置-XX:+UseSerialGC:設(shè)置串行收集器-XX:+UseParallelGC:設(shè)置并行收集器-XX:+UseParalledlOldGC:設(shè)置并行年老代收集器-XX:+UseConcMarkSweepGC:設(shè)置并發(fā)收集器垃圾回收統(tǒng)計(jì)信息-XX:+PrintGC-XX:+PrintGCDetails-XX:+PrintGCTimeStamps-Xloggc:filename并行收集器設(shè)置-XX:ParallelGCThreads=n:設(shè)置并行收集器收集時(shí)使用的CPU數(shù)。并行收集線程數(shù)。-XX:MaxGCPauseMillis=n:設(shè)置并行收集最大暫停時(shí)間-XX:GCTimeRatio=n:設(shè)置垃圾回收時(shí)間占程序運(yùn)行時(shí)間的百分比。公式為1/(1+n)并發(fā)收集器設(shè)置-XX:+CMSIncrementalMode:設(shè)置為增量模式。適用于單CPU情況。-XX:ParallelGCThreads=n:設(shè)置并發(fā)收集器年輕代收集方式為并行收集時(shí),使用的CPU數(shù)。并.6.jvm案例演示內(nèi)存標(biāo)簽相當(dāng)于可視化的jstat命令,用于監(jiān)視收集器管理的虛擬機(jī)內(nèi)存(java堆和永久代)的變化趨勢(shì)。我們通過(guò)下面的一段代碼體驗(yàn)一下它的監(jiān)視功能。運(yùn)行時(shí)設(shè)置的虛擬機(jī)參數(shù)為:存中填充數(shù)據(jù)。publicpublicclassTestMemory{staticclassOOMObject{publicbyte[]placeholder=newbyte[64*1024];}publicstaticvoidfillHeap(intnum)throwsException{ArrayList<OOMObject>list=newArrayList<OOMObject>();for(inti=0;i<num;i++){Thread.sleep(50);list.add(newOOMObject());}System.gc();}publicstaticvoidmain(String[]args)throwsException{fillHeap(1000);Thread.sleep(500000);}}區(qū)都基本上被清空了,但是老年代仍然保持峰值狀態(tài),這說(shuō)明,填充的數(shù)據(jù)在GC后仍然存活,因?yàn)閘ist的作用域沒有結(jié)束。如果把System.gc();移到fillHeap(1000);后,就可以全部回線程相當(dāng)于可視化了jstack命令,遇到線程停頓時(shí),可以使用這個(gè)也簽進(jìn)行監(jiān)控分析。線程長(zhǎng)時(shí)間停頓的主要原因有:等待外部資源(數(shù)據(jù)庫(kù)連接等),死循環(huán)、鎖等待。下面的代碼packagecnjava.jvm;importjavaioBufferedReader;importjava.io.IOException;importjava.io.InputStreamReader;lassTestThread/***死循環(huán)演示*argspublicstaticvoidcreateBusyThread(){Threadthread=newThread(newRunnable(){@Overridepublicvoidrun(){System.out.println("createBusyThread");while(true);}testBusyThread");thread.start();}/***線程鎖等待*argspublicstaticvoidcreateLockThread(finalObjectlock){Threadthread=newThread(newRunnable(){@Overridepublicvoidrun(){System.out.println("createLockThread");synchronized(lock){try{}catch(InterruptedExceptione){intStackTrace}}}},"testLockThread");thread.start();}publicstaticvoidmain(String[]args)throwsException{BufferedReaderbr=newBufferedReader(newInputStreamReader(System.in));createBusyThreadObjectobject=newObject();createLockThread(object);}}main線程:追蹤到需要鍵盤錄入testBusyThread線程:線程阻塞在18行的while(true),直到線程切換,很耗性能packagepackagecnjava.jvm;publicclassTestDeadThreadimplementsRunnable{intab;publicTestDeadThread(inta,intb){this.a=a;this.b=b;}@Overridepublicvoidrun(){System.out.println("createDeadThread");ueOfaeOfbSystem.out.println(a+b);}}}publicstaticvoidmain(String[]args){forfor(inti=0;i<100;i++){newThread(newTestDeadThread(1,2)).start();newThread(newTestDeadThread(2,1)).start();}}}點(diǎn)擊檢查死鎖,會(huì)出現(xiàn)死鎖的詳情。threadthread持有,相反亦是,造成死鎖。.7.java動(dòng)態(tài)代理、反射.7.1.反射通過(guò)反射的方式可以獲取class對(duì)象中的屬性、方法、構(gòu)造函數(shù)等,一下是實(shí)例:ackagecnjavareflectimportjava.lang.reflect.Constructor;importjava.lang.reflect.Field;importjava.lang.reflect.Method;importjava.util.ArrayList;importjava.util.List;importorg.junit.Before;tpublicclassMyReflect{publicStringclassName=null;@SuppressWarnings("rawtypes")publicClasspersonClass=null;/***@throwsException@Beforepublicvoidinit()throwsException{className="cn.java.reflect.Person";personClass=Class.forName(className);}/**publicvoidgetClassName()throwsException{System.out.println(personClass);}/**class對(duì)象的另一種方式publicvoidgetClassName2()throwsException{System.out.println(Person.class);}/***創(chuàng)建一個(gè)class文件表示的真實(shí)對(duì)象,底層會(huì)調(diào)用空參數(shù)的構(gòu)造方法publicvoidgetNewInstance()throwsException{System.out.println(personClass.newInstance());}/***獲取非私有的構(gòu)造函數(shù)@SuppressWarnings({"rawtypes","unchecked"})publicvoidgetPublicConstructor()throwsException{Constructorconstructor=personClass.getConstructor(Long.class,String.class);Personperson=(Person)constructor.newInstance(100L,"zhangsan");System.out.println(person.getId());System.out.println(person.getName());}/***獲得私有的構(gòu)造函數(shù)@SuppressWarnings({"rawtypes","unchecked"})publicvoidgetPrivateConstructor()throwsException{Constructorcon=personClass.getDeclaredConstructor(String.class);con.setAccessible(true);//強(qiáng)制取消Java的權(quán)限檢測(cè)Personperson2=(Person)con.newInstance("zhangsan");System.out.println(person2.getName());}/***獲取非私有的成員變量@SuppressWarnings({"rawtypes","unchecked"})publicvoidgetNotPrivateField()throwsException{Constructorconstructor=personClass.getConstructor(Long.class,String.class);Objectobj=constructor.newInstance(100L,"zhangsan");Fieldfield=personClass.getField("name");field.set(obj,"lisi");System.out.println(field.get(obj));}/***獲取私有的成員變量@SuppressWarnings({"rawtypes","unchecked"})publicvoidgetPrivateField()throwsException{Constructorconstructor=personClass.getConstructor(Long.class);Objectobj=constructor.newInstance(100L);Fieldfield2=personClass.getDeclaredField("id");field2.setAccessible(true);//強(qiáng)制取消Java的權(quán)限檢測(cè)field2.set(obj,10000L);System.out.println(field2.get(obj));}/***獲取非私有的成員函數(shù)@SuppressWarnings({"unchecked"})publicvoidgetNotPrivateMethod()throwsException{System.out.println(personClass.getMethod("toString"));Objectobj=personClass.newInstance();//獲取空參的構(gòu)造函數(shù)Objectobject=personClass.getMethod("toString").invoke(obj);System.out.println(object);}/***獲取私有的成員函數(shù)@SuppressWarnings("unchecked")publicvoidgetPrivateMethod()throwsException{Objectobj=personClass.newInstance();//獲取空參的構(gòu)造函數(shù)Methodmethod=personClass.getDeclaredMethod("getSomeThing");method.setAccessible(true);Objectvalue=method.invoke(obj);System.out.println(value);}/***publicvoidotherMethod()throwsException{//當(dāng)前加載這個(gè)class文件的那個(gè)類加載器對(duì)象System.out.println(personClass.getClassLoader());//獲取某個(gè)類實(shí)現(xiàn)的所有接口Class[]interfaces=personClass.getInterfaces();for(Classclass1:interfaces){System.out.println(class1);}//反射當(dāng)前這個(gè)類的直接父類System.out.println(personClass.getGenericSuperclass());/***getResourceAsStream這個(gè)方法可以獲取到一個(gè)輸入流,這個(gè)輸入流會(huì)關(guān)聯(lián)到name所表示的那個(gè)文件上。path對(duì)路徑,最終還是由ClassLoader獲取資源。System.out.println(personClass.getResourceAsStream("/perties"));//默認(rèn)則是從ClassPath根下獲取,path不能以’/'開頭,最終是由ClassLoader獲System.out.println(personClass.getResourceAsStream("/perties"));//判斷當(dāng)前的Class對(duì)象表示是否是數(shù)組System.out.println(personClass.isArray());System.out.println(newString[3].getClass().isArray());//判斷當(dāng)前的

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論