一、本地(Native)方法
一個(gè)本地方法就是一個(gè) Java 調(diào)用非 Java 代碼的接口,一個(gè)本地方法的實(shí)現(xiàn)由非Java 語言實(shí)現(xiàn),比如 C 語言。這個(gè)特征并非 Java 特有,很多編程語言都有這一機(jī)制。
在定義一個(gè)本地方法時(shí),并不提供實(shí)現(xiàn)體(有些想定義一個(gè)接口),因?yàn)?strong>其實(shí)體是由非 java 語言在外面實(shí)現(xiàn)
本地接口的作用是融合不同的編程語言為 Java 所用,它的初衷是融合 C/C++ 程序。
使用本地方法的目的
1.與環(huán)境交互
2.與操作系統(tǒng)交互
3.Sun‘Java
二、逃逸分析與標(biāo)量替換
逃逸分析:是JVM為了優(yōu)化對象分配而做的一種優(yōu)化措施。發(fā)生在第一步判斷對象是否可以在棧上分配的時(shí)候,JVM通過逃逸分析確定該對象不會被外部訪問。如果不會逃逸可以將該對象在棧上分配內(nèi)存,這樣該對象所占用的內(nèi)存空間就可以隨棧幀出棧而銷毀,節(jié)約堆內(nèi)存,減輕GC的壓力。
標(biāo)量替換:通過逃逸分析確定該對象不會被外部訪問,并且對象可以被進(jìn)一步分解時(shí),JVM不會創(chuàng)建該對象,而是將該對象成員變量分解若干個(gè)被這個(gè)方法使用的成員變量所代替,這些代替的成員變量在棧幀或寄存器上分配空間,這樣就不會因?yàn)闆]有一大塊連續(xù)空間導(dǎo)致對象內(nèi)存不夠分配。
三、CAS
在解決對象創(chuàng)建時(shí)提到了有兩種可選方案:其中一種是對分配內(nèi)存空間的動作進(jìn)行同步處理,采用CAS配上失敗重試的方式保證更新操作的原子性;(另外一種采用本地線程分配緩沖區(qū))
CAS算法是硬件對于并發(fā)操作的支持,其中包含了三個(gè)操作數(shù):內(nèi)存值V,預(yù)估值A(chǔ)和更新值B。沒當(dāng)要執(zhí)行更新操作時(shí),會先在同步方法中比較內(nèi)存值和預(yù)估值是否相等,如果相等才會用更新值替換內(nèi)存值,否則什么也不做。
四、堆轉(zhuǎn)儲快照
堆轉(zhuǎn)儲是Java內(nèi)存的快照, 它包含有關(guān)快照觸發(fā)時(shí)堆中Java對象和類的信息,是一個(gè) 診斷任何與Java內(nèi)存相關(guān)的問題都是至關(guān)重要的工件。獲取堆轉(zhuǎn)儲的幾個(gè)方法:
1.識別流程編號
2.jmap工具捕獲堆轉(zhuǎn)儲
3.通過傳遞'-XX:+ HeapDumpOnOutOfMemoryError'系統(tǒng)屬性來在JVM遇到OutOfMemoryError時(shí)捕獲堆轉(zhuǎn)儲。
五、內(nèi)存泄漏與內(nèi)存溢出
內(nèi)存溢出:(out of memory)通俗理解就是內(nèi)存不夠,比如創(chuàng)建對象時(shí),對象的總內(nèi)存超出了堆內(nèi)存,就叫內(nèi)存溢出。
內(nèi)存泄漏:(Memory Leak)是指程序中己動態(tài)分配的堆內(nèi)存由于某種原因程序未釋放或無法釋放,造成系統(tǒng)內(nèi)存的浪費(fèi),導(dǎo)致程序運(yùn)行速度減慢甚至系統(tǒng)崩潰等嚴(yán)重后果
六、JAR文件
JAR文件是一種軟件包文件格式,通常用于聚合大量的Java類文件、相關(guān)的元數(shù)據(jù)和資源文件到一個(gè)文件,以便開發(fā)Java程序。
JAR文件是一種歸檔文件,以ZIP格式構(gòu)建,以.jar為文件擴(kuò)展名。用戶可以使用JDK自帶的jar命令創(chuàng)建或提取JAR文件。也可以使用其他zip壓縮工具,不過壓縮時(shí)zip文件頭里的條目順序很重要,因?yàn)镸anifest文件常需放在首位。JAR文件內(nèi)的文件名是Unicode文本。
一些參數(shù)設(shè)置
1.-Xmx、-Xms、-Xss
-Xms:是指設(shè)定程序啟動時(shí)占用內(nèi)存大小。
-Xmx:是指設(shè)定程序運(yùn)行期間最大可占用的內(nèi)存大小。(將-Xms與-Xmx值設(shè)置一樣可以避免堆內(nèi)存自動擴(kuò)展)
2.-XX:+/-UseTLAB與-XX:+TLABSize
TLAB:本地線程分配緩沖區(qū)
-XX:+UseTLAB設(shè)置是否使用TLAB
-XX:+TLABSize 設(shè)置TLAB大小
3.-XX:FieldsAllocationStyle
對象中,實(shí)例數(shù)據(jù)部分的存儲順序會受到虛擬機(jī)分配策略參數(shù),即-XX:FieldsAllocationStyle參數(shù)的影響
類型0, 引用在原始類型前面, 然后依次是longs/doubles, ints, shorts/chars, bytes, 最后是填充字段, 以滿足對其要求.
類型1, 引用在原始類型后面
類型2, JVM在布局時(shí)會盡量使父類對象和子對象挨在一起。
4.+XX:CompactFields
對象實(shí)例子數(shù)據(jù)存儲時(shí),相同寬度的字段總是被分配到一起存儲 ,在滿足這個(gè)前提條件的情況下,在父類中定義的變量會出現(xiàn)在子類之前。
但是如果將+XX:CompactFields參數(shù)值為true(默認(rèn)就為true),那子類之中較窄的變量也允許插入父類變量的空隙之中,以節(jié)省出一點(diǎn)點(diǎn)空間。
5.-XX:+HeapDumpOnOutOf-MemoryError
JVM發(fā)生OOM時(shí),-XX:+HeapDumpOnOutOfMemoryError參數(shù)表示自動生成DUMP文件。也可以指定文件名稱,例如:-XX:HeapDumpPath=${目錄}/java_heapdump.hprof。如果不指定文件名,默認(rèn)為:java<pid><date><time>heapDump.hprof。
6.-Xoss與-Xss
-Xoss參數(shù):設(shè)置本地方法棧大小,雖然存在,但實(shí)際上是沒有任何效果的。
-Xss:設(shè)置棧最小容量。參數(shù)-Xss128k可以正常用于32位Windows系統(tǒng)下的JDK 6,但是如果用于64位Windows系統(tǒng)下的JDK 11,則會提示棧容量最小不能低于180K,而在Linux下這個(gè)值則可能是228K,如果低于這個(gè)最小限制,HotSpot虛擬器啟動時(shí)會給出如下提示
The Java thread stack size specified is too small. Specify at least 228k
7.-XX:PermSize和-XX:MaxPermSize
-XX:PermSize和-XX:MaxPermSize用來限制永久代參數(shù)大小
8.-XX:MaxMeta-spaceSize與-XX:MaxPermSize
兩個(gè)參數(shù)都是限制方法區(qū)容量(最大),MaxMeta-spaceSize在JDK8以上版本使用,-XX:MaxPermSize在JDK7版本使用
9.-XX:MaxMetaspaceSize與-XX:MetaspaceSize
-XX:MaxMetaspaceSize:設(shè)置元空間最大值,默認(rèn)是-1,即不限制,或者說只受限于本地內(nèi)存大小。
XX:MetaspaceSize:指定元空間的初始空間大小,以字節(jié)為單位
-XX:MinMetaspaceFreeRatio:作用是在垃圾收集之后控制最小的元空間剩余容量的百分比,可減少因?yàn)樵臻g不足導(dǎo)致的垃圾收集的頻率。
-XX:Max-MetaspaceFreeRatio,用于控制最大的元空間剩余容量的百分比。
10.-XX:MaxDirectMemorySize
通過-XX:MaxDirectMemorySize參數(shù)指定直接內(nèi)存(Direct Memory)的容量大小。
11.Xnoclassgc參數(shù)
HotSpot虛擬機(jī)提供了Xnoclassgc參數(shù)進(jìn)行控制方法區(qū)堆類型的回收,還可以使用-verbose:class以及-XX:+TraceClass-Loading、-XX: +TraceClassUnLoading查看類加載和卸載信息,其中-verbose:class和-XX:+TraceClassLoading可以在 Product版的虛擬機(jī)中使用,-XX:+TraceClassUnLoading參數(shù)需要FastDebug版的虛擬機(jī)支持。
12.-XX:+UseCondCardMark
-XX:+UseCondCardMark參數(shù)用來決定是否開啟卡表更新的條件判斷。開啟會增加一次額外判斷的開銷,但能夠避免偽共享問題。
13.-XX:SurvivorRatio、-XX: PretenureSizeThreshold
-XX:SurvivorRatio:定義了新生代中Eden區(qū)域和Survivor區(qū)域(的比例,默認(rèn)為8,也就是說Eden占新生代的8/10。
-XX:PretenureSizeThreshold參數(shù):設(shè)置一個(gè)判斷閾值,當(dāng)大對象的值大于閾值值的對象直接在老年代分配。這樣做的目的就是避免在Eden區(qū)及兩個(gè)Survivor區(qū) 之間來回復(fù)制,產(chǎn)生大量的內(nèi)存復(fù)制操作。
14:-XX:+/-UseParNewGC
-XX:+UseConcMarkSweepGC:設(shè)定ParNew收集器是激活CMS后的默認(rèn)新生代收集器,也可以使用-XX:+/-UseParNewGC選項(xiàng)來強(qiáng)制指定或者禁用它。JDK9以后取消了這個(gè)參數(shù),意味著ParNew和CMS收集器只能相互配合使用,而不能和其他垃圾收集器配合使用。
15.-XX:ParallelGCThreads
-XX:ParallelGCThreads:表示JVM在進(jìn)行并行GC的時(shí)候,用于GC的線程數(shù)。
16.-XX:MaxGCPauseMillis與-XX:GCTimeRatio參數(shù)-XX:+UseAdaptiveSizePolicy
-XX:MaxGCPauseMillis:Parallel Scavenge收集器收集器控制最大垃圾收集停頓時(shí)間的參數(shù)。
-XX:GCTimeRatio:直接設(shè)置吞吐量大小。
-XX:+UseAdaptiveSizePolicy:打開虛擬機(jī)動態(tài)調(diào)整停頓時(shí)間或者吞吐量參數(shù)的參數(shù)。
17.-XX:CMSInitiatingOccu-pancyFraction
-XX:CMSInitiatingOccu-pancyFraction:調(diào)整CMS的觸發(fā)百分比,適當(dāng)調(diào)高后可以降低內(nèi)存回收頻率,獲取更好的性能。
18.-Xlog
-Xlog參數(shù)包含了HotSpot所有功能的日志。(通過命令行使用)
19.-XX: MaxTenuringThreshold
-XX: MaxTenuringThreshold:對象晉升老年代的年齡閾值。
20.-XX: +TraceClassLoading
-XX: +TraceClassLoading:此參數(shù)用于動態(tài)跟蹤類的加載,此操作是會導(dǎo)致子類加載的。
使用方法(通過命令行使用):先寫一個(gè)java類,比如Test.java;然后先用javac Test.java進(jìn)行編譯,再用java -XX:+TraceClassLoading Test得到加載日志
21.-Client參數(shù)與-Server參數(shù)
使用“-client”強(qiáng)制指定虛擬機(jī)運(yùn)行在客戶端模式。
或“-server”參數(shù)去強(qiáng)制指定虛擬機(jī)運(yùn)行在服務(wù)端模式。
22.-Xint與-Xcomp
-Xint:”強(qiáng)制虛擬機(jī)運(yùn)行于“解釋模式(解釋器)
-Xcomp:”強(qiáng)制虛擬機(jī)運(yùn)行于“編譯模式(編譯器 )
23.-XX:UseCounterDecay與-XX:CounterHalfLifeTime
再判斷熱點(diǎn)代碼時(shí),方法調(diào)用計(jì)數(shù)器統(tǒng)計(jì)的是方法被調(diào)用的相對的執(zhí)行頻率,即一段時(shí)間之內(nèi)方法被調(diào)用的次數(shù)。如果方法的調(diào)用次數(shù)仍然不足以讓它提交給即時(shí)編譯器編譯,那該方法的調(diào)用計(jì)數(shù)器就會被減少一半,這個(gè)過程被稱為方法調(diào)用計(jì)數(shù)器熱度的衰減(Counter Decay),而這段時(shí)間就稱為此方法統(tǒng)計(jì)的半衰周期。
-XX:UseCounterDecay:關(guān)閉熱度衰減,讓方法計(jì)數(shù)器統(tǒng)計(jì)方法調(diào)用的絕對次數(shù)。
-XX:CounterHalfLifeTime:設(shè)置半衰周期的時(shí)間,單位是秒。
24.-XX:+PrintCompilation
-XX:+PrintCompilation:要求虛擬機(jī)在即時(shí)編譯時(shí)將被編譯成本地代碼的方法名稱打印出來,通過此參數(shù)可以查看某個(gè)方法是否被編譯過。