劉紅
摘 要:JAVA語(yǔ)言擁有廣泛的應(yīng)用空間,由于技術(shù)成熟,上手簡(jiǎn)單效果穩(wěn)定因此在很多程序開發(fā)中都選用JAVA語(yǔ)言開發(fā)程序。經(jīng)過(guò)數(shù)代的更迭,其程序的完整性和拓展性得到了大大的提升,但縱觀JAVA語(yǔ)言程序發(fā)展的過(guò)程,其內(nèi)存的低效使用一直是導(dǎo)致其性能無(wú)法突破瓶頸的重要影響因素,本文結(jié)合作者實(shí)際的工作經(jīng)驗(yàn),對(duì)空閑空間、泄露空間、蚍蜉空間三類導(dǎo)致內(nèi)存失效的情況進(jìn)行分開介紹和分析希望能夠幫助更多的程序開發(fā)者和從業(yè)人員能夠更加全面深刻的了解造成JAVA語(yǔ)言程序內(nèi)存低效的因素。
關(guān)鍵詞:JAVA語(yǔ)言;內(nèi)存低效;分析
1.JAVA語(yǔ)言概述
JAVA語(yǔ)言由于其平臺(tái)獨(dú)立性和面向普通消費(fèi)者的特點(diǎn),成為了使用最為廣泛的編程語(yǔ)言之一,在大量的個(gè)人程序網(wǎng)站都占據(jù)重要的份額。JAVA語(yǔ)言編制成字碼節(jié)后在JAVA虛擬機(jī)上進(jìn)行運(yùn)行,其內(nèi)存回收工作由JVM提供的垃圾回收站完成。由于回收站的工作是自動(dòng)進(jìn)行的,所以程序員無(wú)需管理垃圾回收,減輕了程序員的精力,分散情況。很多人對(duì)Java內(nèi)存回收缺乏認(rèn)識(shí),認(rèn)為其通過(guò)自動(dòng)垃圾回收處理的過(guò)程不會(huì)出現(xiàn)問(wèn)題,事實(shí)上java也會(huì)存在內(nèi)存泄漏的情況及有部分存在價(jià)值的對(duì)象無(wú)法被回收,而這些對(duì)象自身所占據(jù)的內(nèi)存空間也無(wú)法得到釋放和循環(huán)使用,導(dǎo)致一部分內(nèi)存空間被占用。當(dāng)這種情況持續(xù)累積下去,當(dāng)gym無(wú)法再重新申請(qǐng)到足夠的內(nèi)存空間時(shí),系統(tǒng)就會(huì)崩潰告警,對(duì)于一些大規(guī)模的應(yīng)用程序,特別是持續(xù)時(shí)間長(zhǎng),需要提供關(guān)鍵服務(wù)的server端程序,這種崩潰即使持續(xù)時(shí)間短,也會(huì)對(duì)其服務(wù)質(zhì)量和管理造成致命打擊,因此是要嚴(yán)格杜絕這種情況出現(xiàn)。使用Java語(yǔ)言進(jìn)行程序編程時(shí),首先要對(duì)這個(gè)內(nèi)在機(jī)理有明確的認(rèn)識(shí),只有在此基礎(chǔ)上才能夠有效規(guī)避內(nèi)存低效使用的情況。
2.Java程序的內(nèi)存低效使用
2.1泄露對(duì)象、蚍蜉對(duì)象、空閑對(duì)象
在使用Java語(yǔ)言進(jìn)行程序編程時(shí)很多內(nèi)存空間的應(yīng)用是不定量的,需根據(jù)當(dāng)時(shí)編譯情況確定,由于變量的存在屬于內(nèi)存空間,需要強(qiáng)制一部分空閑空間用于,在高內(nèi)存占用情況下予以空間填補(bǔ)。但如果是機(jī)械化的保留一定比例或固定容量的空間,又會(huì)使得內(nèi)存容量受到限制,有時(shí)會(huì)產(chǎn)生內(nèi)存空間被浪費(fèi)的情況,因此需要在程序運(yùn)行過(guò)程中采取動(dòng)態(tài)分配的方式,讓其在不需要提前預(yù)留空余空間時(shí)被釋放出來(lái),以提高可使用空間的總?cè)萘?。Java語(yǔ)言內(nèi)存機(jī)制的特點(diǎn)就是其內(nèi)存回收工作完全是由jym提供的垃圾收集器自動(dòng)進(jìn)行的,這個(gè)過(guò)程無(wú)法進(jìn)行人為的干預(yù),所以如果gym垃圾處理程序自身出現(xiàn)了內(nèi)存占用過(guò)多或內(nèi)存使用不合理的情況,在外部機(jī)制下是無(wú)法對(duì)其進(jìn)行控制的,所以也會(huì)給內(nèi)存釋放造成一定的困難。
Java語(yǔ)言編程的程序存在大量生存期較短的臨時(shí)對(duì)象或者一次性對(duì)象,這些對(duì)象一般是未完成某程序運(yùn)行,環(huán)境所添加的一次性產(chǎn)物,這些對(duì)象在后期使用中沒(méi)有任何使用價(jià)值,理論上應(yīng)該在使用之后就自動(dòng)剔除,讓出多余的內(nèi)存空間,但是現(xiàn)實(shí)往往是這些對(duì)象長(zhǎng)期存在占用大量的內(nèi)存,導(dǎo)致GC頻繁啟動(dòng),消耗了大量的程序反應(yīng)時(shí)間。編程人員一般將其稱之為蚍蜉對(duì)象,這些對(duì)象在實(shí)際應(yīng)用中用處極少,但是其存在所占有的內(nèi)存空間卻是長(zhǎng)時(shí)間的,對(duì)于整個(gè)程序運(yùn)作的內(nèi)存動(dòng)態(tài)管理會(huì)造成很大的困難。另一種情況是對(duì)象被分配后長(zhǎng)時(shí)間處于空閑狀態(tài),而又沒(méi)有相應(yīng)的機(jī)制,對(duì)這種長(zhǎng)期處于空閑狀態(tài)的對(duì)象進(jìn)行管理,導(dǎo)致其也許整個(gè)生命周期的使用場(chǎng)景只有很短的時(shí)間,而這類對(duì)象最后會(huì)被GC回收,但從分配到被回收之間需要很長(zhǎng)的周期,90%以上的時(shí)間都處于不活動(dòng)狀態(tài),所以這類事實(shí)上占據(jù)了內(nèi)存空間,但是實(shí)際使用場(chǎng)景和比例極少的對(duì)象程序編程人員將其稱之為空閑對(duì)象。這對(duì)象在處理的過(guò)程中前文所提及的蚍蜉對(duì)象有很多的相似之處。
2.2Java內(nèi)存低效使用的影響
必須應(yīng)用是需要一定的內(nèi)存空間作為支持的,如果內(nèi)存長(zhǎng)期保持低效運(yùn)用狀態(tài),那么可利用的內(nèi)存容量就會(huì)被壓縮,在程序運(yùn)行過(guò)程中也許會(huì)瞬間用完內(nèi)存空間導(dǎo)致gym所能申請(qǐng)的所有內(nèi)存全部被使用完畢,導(dǎo)致jIm崩潰,另一種情況就是導(dǎo)致GC頻繁回收,在回收過(guò)程中持續(xù)占用著機(jī)能,導(dǎo)致程序的運(yùn)行效率受到了影響,通過(guò)對(duì)不同使用對(duì)象的處理和使用在內(nèi)存低效上的對(duì)比,我們可以發(fā)現(xiàn),Java程序?qū)?yīng)泄漏對(duì)象時(shí),泄漏對(duì)象不會(huì)對(duì)GC造成影響,但是會(huì)產(chǎn)生顯著的空間效率影響和時(shí)間效率影響,但目前對(duì)其進(jìn)行檢測(cè)難度簡(jiǎn)單,但對(duì)其進(jìn)行修正則需要花費(fèi)大量的時(shí)間和資源。而蚍蜉對(duì)象其既能夠改變GC同時(shí)對(duì)時(shí)間效率的影響很明顯,但是在空間使用效率的影響方面卻很輕微,目前對(duì)其進(jìn)行檢測(cè)的手段很多檢測(cè)過(guò)程較為簡(jiǎn)單,同時(shí)修的難度也不大,空閑對(duì)象能夠?qū)C產(chǎn)生影響,會(huì)對(duì)空間使用效率和時(shí)間使用效率都產(chǎn)生極大的影響,對(duì)其進(jìn)行檢測(cè)難度很大,同時(shí)對(duì)其進(jìn)行處理的難度也很大。
通過(guò)對(duì)三種對(duì)象造成的影響進(jìn)行對(duì)比,我們可以發(fā)現(xiàn)蚍蜉對(duì)象在GC啟動(dòng)之后就會(huì)被回收,所以來(lái)不及對(duì)空間效率造成太嚴(yán)重的影響,而泄露對(duì)象和空閑對(duì)象,則會(huì)由于持續(xù)占據(jù)內(nèi)存,無(wú)法被循環(huán)利用,造成了空間效率的降低。但在實(shí)際的程序運(yùn)行過(guò)程中蚍蜉對(duì)象的存在會(huì)導(dǎo)致回收機(jī)制頻繁啟動(dòng),這會(huì)造成時(shí)間效率的降低。而由于泄露對(duì)象和空閑對(duì)象會(huì)增加GC的檢測(cè)時(shí)間,所以也在一定程度上降低了程序的時(shí)間效率。在檢測(cè)修正的層面來(lái)分析,當(dāng)gym關(guān)閉前,可以對(duì)泄漏對(duì)象進(jìn)行檢測(cè),檢測(cè)到的幾率很大,而且由于其整體的檢測(cè)難度較低,所以一般會(huì)保持很強(qiáng)的準(zhǔn)確性。而泄露對(duì)象一般是由于自身的邏輯缺陷所造成的,所以對(duì)此類問(wèn)題進(jìn)行修正時(shí),首先要對(duì)其行為邏輯進(jìn)行分析,這就增加了修正的難度。蚍蜉對(duì)象一般是臨時(shí)性出現(xiàn)的,所以通過(guò)在單位時(shí)間內(nèi)對(duì)GC的活動(dòng)頻率進(jìn)行檢測(cè),即可判斷是否存在大量的相似對(duì)象,簡(jiǎn)單的對(duì)其進(jìn)行創(chuàng)建位置進(jìn)行修正,因此對(duì)其進(jìn)行檢測(cè)和修正的難度理論上來(lái)說(shuō)都不大,對(duì)于空閑對(duì)象必須要對(duì)整個(gè)對(duì)象的生命周期的行為信息進(jìn)行綜合分析才能判斷其活動(dòng)其和空閑期所以對(duì)其進(jìn)行檢測(cè)數(shù)據(jù)化費(fèi)的計(jì)算資源更多,所以用時(shí)更長(zhǎng)而對(duì)其進(jìn)行修正時(shí),要考慮到對(duì)象的使用邏輯和行為邏輯,也要占用大量的資源和時(shí)間,所以對(duì)其進(jìn)行修正的難度也很大。
3.當(dāng)前的研究工作成果
很多的泄露對(duì)象都是在操作時(shí)被臨時(shí)創(chuàng)建的,但是卻在操作結(jié)束之后沒(méi)有得到及時(shí)的回收,所以如果設(shè)定臨時(shí)對(duì)象的期望生命周期和存貨周期,如果其超過(guò)了期望生活周期,那么對(duì)象就是泄露對(duì)象,針對(duì)Java中的數(shù)組提出一個(gè)結(jié)合前項(xiàng)數(shù)據(jù)流分析和后項(xiàng)控制流分析的算法,就可以增加對(duì)此類對(duì)象的分析效率。
蚍蜉對(duì)象而生存周期較短,會(huì)引起頻繁的GC啟動(dòng),因此在進(jìn)行程序檢測(cè)時(shí)只要使用能夠?qū)C程序啟動(dòng)敏感的程序就可以大概率的覆蓋此類對(duì)象的所在區(qū)域。由于空閑對(duì)象的生存周期較長(zhǎng),對(duì)其進(jìn)行檢測(cè)需要符合更多方面的信息,所以對(duì)整個(gè)中其行為和對(duì)象活動(dòng)都要進(jìn)行檢測(cè),在目前看來(lái)還沒(méi)有一個(gè)能夠有效減少計(jì)算時(shí)間和資源的方式。
4.當(dāng)前工作成效不足的原因分析
此前相關(guān)研究人員在進(jìn)行對(duì)象研究時(shí),對(duì)于泄露對(duì)象的研究方向集中在如何對(duì)其進(jìn)行準(zhǔn)確檢測(cè),在如何修正方面沒(méi)有太多的資源投入,導(dǎo)致目前有效的解決方案數(shù)量較少,不能對(duì)空閑空間進(jìn)行相應(yīng)的修正和檢測(cè),多數(shù)工具都要用戶對(duì)程序行為的實(shí)現(xiàn)具有基礎(chǔ)了解,才能夠發(fā)揮到工具的效果,我肯定會(huì)限制相應(yīng)的工具普及和推廣的速度和范圍,同時(shí)也增加了更多的不確定性。
結(jié)束語(yǔ):
雖然當(dāng)前研究人員對(duì)一些可觀察信息在一定程度上反映了對(duì)象行為和使用邏輯,禁行了行為勾勒,但是整個(gè)畫像并不全面,如果想要對(duì)內(nèi)存低效使用進(jìn)行更加深入的檢測(cè)和修正,就必須全面的對(duì)所有對(duì)象的行為邏輯和相應(yīng)的產(chǎn)生信息進(jìn)行覆蓋,獲取最全面的數(shù)據(jù)支持。
參考文獻(xiàn):
[1]柳永坡,賈曉霞,吳際, 等.Java程序內(nèi)存低效使用問(wèn)題的分析[J].計(jì)算機(jī)工程,2008,34(23):84-85,91. DOI:10.3969/j.issn.1000-3428.2008.23.031.
[2]李文杰.Java程序內(nèi)存使用分析技術(shù)研究[D].江蘇:中國(guó)礦業(yè)大學(xué),2016.
[3]王志花.Java程序內(nèi)存行為探究[J].硅谷,2012,(7):182-182,190.