JVM理解其實(shí)并不難!

我的CSDN博客同步發(fā)布:JVM理解其實(shí)并不難丐箩!

在閱讀本文之前摇邦,先向大家強(qiáng)烈推薦一下周志明的《深入理解Java虛擬機(jī)》這本書(shū)。

前些天面試了阿里的實(shí)習(xí)生雏蛮,問(wèn)到關(guān)于Dalvik虛擬機(jī)能不能執(zhí)行class文件涎嚼,我當(dāng)時(shí)的回答是不能阱州,但是它執(zhí)行的是class轉(zhuǎn)換的dex文件挑秉。當(dāng)面試官繼續(xù)問(wèn),為什么不能執(zhí)行class文件時(shí)苔货,我卻只能回答Dalvik虛擬機(jī)內(nèi)部的優(yōu)化原因犀概,卻不能正確回答具體的原因。其實(shí)周志明的這本書(shū)就有回答:Dakvik并不是一個(gè)Java虛擬機(jī)夜惭,它沒(méi)有遵循Java虛擬機(jī)規(guī)范姻灶,不能執(zhí)行Java的class文件,使用的是寄存器架構(gòu)而不是JVM中常見(jiàn)的棧架構(gòu)诈茧,但是它與Java又有著千絲萬(wàn)縷的關(guān)系产喉,它執(zhí)行的dex文件可以通過(guò)class文件轉(zhuǎn)化而來(lái)

其實(shí)在本科期間敢会,就有接觸過(guò)《深入理解Java虛擬機(jī)》曾沈,但是一直以來(lái)都沒(méi)去仔細(xì)研讀,現(xiàn)在回頭想想實(shí)在是覺(jué)得可惜鸥昏!研一期間花了不少時(shí)間研讀塞俱,現(xiàn)在準(zhǔn)備找工作了,發(fā)現(xiàn)好多內(nèi)容看了又忘吏垮。索性寫(xiě)一篇文章障涯,把這本書(shū)的知識(shí)點(diǎn)做一個(gè)總結(jié)。當(dāng)然了膳汪,如果你想看比較詳細(xì)的內(nèi)容唯蝶,可以翻看《深入理解Java虛擬機(jī)》。

JVM內(nèi)存區(qū)域

我們?cè)诰帉?xiě)程序時(shí)遗嗽,經(jīng)常會(huì)遇到OOM(out of Memory)以及內(nèi)存泄漏等問(wèn)題粘我。為了避免出現(xiàn)這些問(wèn)題,我們首先必須對(duì)JVM的內(nèi)存劃分有個(gè)具體的認(rèn)識(shí)媳谁。JVM將內(nèi)存主要?jiǎng)澐譃椋悍椒▍^(qū)涂滴、虛擬機(jī)棧、本地方法棧晴音、堆柔纵、程序計(jì)數(shù)器。JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)如下:

JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)

程序計(jì)數(shù)器

程序計(jì)數(shù)器是線程私有的區(qū)域锤躁,很好理解嘛~搁料,每個(gè)線程當(dāng)然得有個(gè)計(jì)數(shù)器記錄當(dāng)前執(zhí)行到那個(gè)指令。占用的內(nèi)存空間小,可以把它看成是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號(hào)指示器郭计。如果線程在執(zhí)行Java方法霸琴,這個(gè)計(jì)數(shù)器記錄的是正在執(zhí)行的虛擬機(jī)字節(jié)碼指令地址;如果執(zhí)行的是Native方法昭伸,這個(gè)計(jì)數(shù)器的值為空(Undefined)梧乘。此內(nèi)存區(qū)域是唯一一個(gè)在Java虛擬機(jī)規(guī)范中沒(méi)有規(guī)定任何OutOfMemoryError情況的區(qū)域

Java虛擬機(jī)棧

與程序計(jì)數(shù)器一樣庐杨,Java虛擬機(jī)棧也是線程私有的选调。其生命周期與線程相同。如何理解虛擬機(jī)棧呢灵份?本質(zhì)上來(lái)講仁堪,就是個(gè)棧。里面存放的元素叫棧幀填渠,棧幀好像很復(fù)雜的樣子弦聂,其實(shí)它很簡(jiǎn)單!它里面存放的是一個(gè)函數(shù)的上下文氛什,具體存放的是執(zhí)行的函數(shù)的一些數(shù)據(jù)莺葫。執(zhí)行的函數(shù)需要的數(shù)據(jù)無(wú)非就是局部變量表(保存函數(shù)內(nèi)部的變量)、操作數(shù)棧(執(zhí)行引擎計(jì)算時(shí)需要)屉更,方法出口等等徙融。

執(zhí)行引擎每調(diào)用一個(gè)函數(shù)時(shí),就為這個(gè)函數(shù)創(chuàng)建一個(gè)棧幀瑰谜,并加入虛擬機(jī)棧欺冀。換個(gè)角度理解,每個(gè)函數(shù)從調(diào)用到執(zhí)行結(jié)束萨脑,其實(shí)是對(duì)應(yīng)一個(gè)棧幀的入棧和出棧隐轩。

注意這個(gè)區(qū)域可能出現(xiàn)的兩種異常:一種是StackOverflowError,當(dāng)前線程請(qǐng)求的棧深度大于虛擬機(jī)所允許的深度時(shí)渤早,會(huì)拋出這個(gè)異常职车。制造這種異常很簡(jiǎn)單:將一個(gè)函數(shù)反復(fù)遞歸自己,最終會(huì)出現(xiàn)棧溢出錯(cuò)誤(StackOverflowError)鹊杖。另一種異常是OutOfMemoryError異常悴灵,當(dāng)虛擬機(jī)棧可以動(dòng)態(tài)擴(kuò)展時(shí)(當(dāng)前大部分虛擬機(jī)都可以)骂蓖,如果無(wú)法申請(qǐng)足夠多的內(nèi)存就會(huì)拋出OutOfMemoryError积瞒,如何制作虛擬機(jī)棧OOM呢,參考一下代碼:

public void stackLeakByThread(){
    while(true){
        new Thread(){
            public void run(){
                while(true){
                }
            }
        }.start()
    }
}

這段代碼有風(fēng)險(xiǎn)登下,可能會(huì)導(dǎo)致操作系統(tǒng)假死茫孔,請(qǐng)謹(jǐn)慎使用~~~

本地方法棧

本地方法棧與虛擬機(jī)棧所發(fā)揮的作用很相似叮喳,他們的區(qū)別在于虛擬機(jī)棧為執(zhí)行Java代碼方法服務(wù),而本地方法棧是為Native方法服務(wù)缰贝。與虛擬機(jī)棧一樣馍悟,本地方法棧也會(huì)拋出StackOverflowError和OutOfMemoryError異常。

Java堆

Java堆可以說(shuō)是虛擬機(jī)中最大一塊內(nèi)存了剩晴。它是所有線程所共享的內(nèi)存區(qū)域锣咒,幾乎所有的實(shí)例對(duì)象都是在這塊區(qū)域中存放。當(dāng)然李破,睡著JIT編譯器的發(fā)展宠哄,所有對(duì)象在堆上分配漸漸變得不那么“絕對(duì)”了。

Java堆是垃圾收集器管理的主要區(qū)域嗤攻。由于現(xiàn)在的收集器基本上采用的都是分代收集算法,所有Java堆可以細(xì)分為:新生代和老年代诽俯。在細(xì)致分就是把新生代分為:Eden空間妇菱、From Survivor空間、To Survivor空間暴区。當(dāng)堆無(wú)法再擴(kuò)展時(shí)闯团,會(huì)拋出OutOfMemoryError異常。

方法區(qū)

方法區(qū)存放的是類(lèi)信息仙粱、常量房交、靜態(tài)變量等。方法區(qū)是各個(gè)線程共享區(qū)域伐割,很容易理解候味,我們?cè)趯?xiě)Java代碼時(shí),每個(gè)線程度可以訪問(wèn)同一個(gè)類(lèi)的靜態(tài)變量對(duì)象隔心。由于使用反射機(jī)制的原因白群,虛擬機(jī)很難推測(cè)那個(gè)類(lèi)信息不再使用,因此這塊區(qū)域的回收很難硬霍。另外帜慢,對(duì)這塊區(qū)域主要是針對(duì)常量池回收,值得注意的是JDK1.7已經(jīng)把常量池轉(zhuǎn)移到堆里面了唯卖。同樣粱玲,當(dāng)方法區(qū)無(wú)法滿足內(nèi)存分配需求時(shí),會(huì)拋出OutOfMemoryError拜轨。
制造方法區(qū)內(nèi)存溢出抽减,注意,必須在JDK1.6及之前版本才會(huì)導(dǎo)致方法區(qū)溢出撩轰,原因后面解釋,執(zhí)行之前胯甩,可以把虛擬機(jī)的參數(shù)-XXpermSize和-XX:MaxPermSize限制方法區(qū)大小昧廷。

List<String> list =new ArrayList<String>();
int i =0;
while(true){
    list.add(String.valueOf(i).intern());
} 

運(yùn)行后會(huì)拋出java.lang.OutOfMemoryError:PermGen space異常。
解釋一下偎箫,Stringintern()函數(shù)作用是如果當(dāng)前的字符串在常量池中不存在木柬,則放入到常量池中。上面的代碼不斷將字符串添加到常量池淹办,最終肯定會(huì)導(dǎo)致內(nèi)存不足眉枕,拋出方法區(qū)的OOM。

下面解釋一下怜森,為什么必須將上面的代碼在JDK1.6之前運(yùn)行速挑。我們前面提到,JDK1.7后副硅,把常量池放入到堆空間中姥宝,這導(dǎo)致intern()函數(shù)的功能不同,具體怎么個(gè)不同法恐疲,且看看下面代碼:

String str1 =new StringBuilder("hua").append("chao").toString();
System.out.println(str1.intern()==str1);

String str2=new StringBuilder("ja").append("va").toString();
System.out.println(str2.intern()==str2);

這段代碼在JDK1.6和JDK1.7運(yùn)行的結(jié)果不同腊满。JDK1.6結(jié)果是:false,false ,JDK1.7結(jié)果是true, false培己。原因是:JDK1.6中碳蛋,intern()方法會(huì)吧首次遇到的字符串實(shí)例復(fù)制到常量池中,返回的也是常量池中的字符串的引用省咨,而StringBuilder創(chuàng)建的字符串實(shí)例是在堆上面肃弟,所以必然不是同一個(gè)引用,返回false零蓉。在JDK1.7中笤受,intern不再?gòu)?fù)制實(shí)例,常量池中只保存首次出現(xiàn)的實(shí)例的引用壁公,因此intern()返回的引用和由StringBuilder創(chuàng)建的字符串實(shí)例是同一個(gè)感论。為什么對(duì)str2比較返回的是false呢?這是因?yàn)槲刹幔琂VM中內(nèi)部在加載類(lèi)的時(shí)候比肄,就已經(jīng)有"java"這個(gè)字符串,不符合“首次出現(xiàn)”的原則囊陡,因此返回false芳绩。

垃圾回收(GC)

JVM的垃圾回收機(jī)制中,判斷一個(gè)對(duì)象是否死亡撞反,并不是根據(jù)是否還有對(duì)象對(duì)其有引用妥色,而是通過(guò)可達(dá)性分析。對(duì)象之間的引用可以抽象成樹(shù)形結(jié)構(gòu)遏片,通過(guò)樹(shù)根(GC Roots)作為起點(diǎn)嘹害,從這些樹(shù)根往下搜索撮竿,搜索走過(guò)的鏈稱為引用鏈,當(dāng)一個(gè)對(duì)象到GC Roots沒(méi)有任何引用鏈相連時(shí)笔呀,則證明這個(gè)對(duì)象是不可用的幢踏,該對(duì)象會(huì)被判定為可回收的對(duì)象。

那么那些對(duì)象可作為GC Roots呢许师?主要有以下幾種:

1.虛擬機(jī)棧(棧幀中的本地變量表)中引用的對(duì)象房蝉。
2.方法區(qū)中類(lèi)靜態(tài)屬性引用的對(duì)象。
3.方法區(qū)中常量引用的對(duì)象
4.本地方法棧中JNI(即一般說(shuō)的Native方法)引用的對(duì)象微渠。

另外搭幻,Java還提供了軟引用和弱引用,這兩個(gè)引用是可以隨時(shí)被虛擬機(jī)回收的對(duì)象逞盆,我們將一些比較占內(nèi)存但是又可能后面用的對(duì)象檀蹋,比如Bitmap對(duì)象,可以聲明為軟引用貨弱引用纳击。但是注意一點(diǎn)续扔,每次使用這個(gè)對(duì)象時(shí)候,需要顯示判斷一下是否為null焕数,以免出錯(cuò)。

三種常見(jiàn)的垃圾收集算法

1.標(biāo)記-清除算法

首先刨啸,通過(guò)可達(dá)性分析將可回收的對(duì)象進(jìn)行標(biāo)記堡赔,標(biāo)記后再統(tǒng)一回收所有被標(biāo)記的對(duì)象,標(biāo)記過(guò)程其實(shí)就是可達(dá)性分析的過(guò)程设联。這種方法有2個(gè)不足點(diǎn):效率問(wèn)題善已,標(biāo)記和清除兩個(gè)過(guò)程的效率都不高;另一個(gè)是空間問(wèn)題离例,標(biāo)記清除之后會(huì)產(chǎn)生大量的不連續(xù)的內(nèi)存碎片换团。

2.復(fù)制算法

為了解決效率問(wèn)題,復(fù)制算法是將內(nèi)存分為大小相同的兩塊宫蛆,每次只使用其中一塊艘包。當(dāng)這塊內(nèi)存用完了,就將還存活的對(duì)象復(fù)制到另一塊內(nèi)存上面耀盗。然后再把已經(jīng)使用過(guò)的內(nèi)存一次清理掉想虎。這使得每次只對(duì)半個(gè)區(qū)域進(jìn)行垃圾回收,內(nèi)存分配時(shí)也不用考慮內(nèi)存碎片情況叛拷。

但是舌厨,這代價(jià)實(shí)在是讓人無(wú)法接受,需要犧牲一般的內(nèi)存空間忿薇。研究發(fā)現(xiàn)裙椭,大部分對(duì)象都是“朝生夕死”躏哩,所以不需要安裝1:1比例劃分內(nèi)存空間,而是將內(nèi)存分為一塊較大的Eden空間和兩塊較小的Survivor空間揉燃,每次使用Eden空間和一塊Survivor空間扫尺,默認(rèn)比例為Eden:Survivor=8:1.新生代區(qū)域就是這么劃分,每次實(shí)例在Eden和一塊Survivor中分配你雌,回收時(shí)器联,將存活的對(duì)象復(fù)制到剩下的另一塊Survivor。這樣只有10%的內(nèi)存會(huì)被浪費(fèi)婿崭,但是帶來(lái)的效率卻很高拨拓。當(dāng)剩下的Survivor內(nèi)存不足時(shí),可以去老年代內(nèi)存進(jìn)行分配擔(dān)保氓栈。如何理解分配擔(dān)保呢渣磷,其實(shí)就是,內(nèi)存不足時(shí)授瘦,去老年代內(nèi)存空間分配醋界,然后等新生代內(nèi)存緩過(guò)來(lái)了之后,把內(nèi)存歸還給老年代提完,保持新生代中的Eden:Survivor=8:1.另外形纺,兩個(gè)Survivor分別有自己的名稱:From Survivor、To Survivor徒欣。二者身份經(jīng)常調(diào)換逐样,即有時(shí)這塊內(nèi)存與Eden一起參與分配,有時(shí)是另一塊打肝。因?yàn)樗麄冎g經(jīng)常相互復(fù)制脂新。

3.標(biāo)記-整理算法

標(biāo)記整理算法很簡(jiǎn)單,就是先標(biāo)記需要回收的對(duì)象粗梭,然后把所有存活的對(duì)象移動(dòng)到內(nèi)存的一端争便。這樣的好處是避免了內(nèi)存碎片。

類(lèi)加載機(jī)制

類(lèi)從被加載到虛擬機(jī)內(nèi)存開(kāi)始断医,到卸載出內(nèi)存為止滞乙,整個(gè)生命周期包括:加載、驗(yàn)證孩锡、準(zhǔn)備酷宵、解析、初始化躬窜、使用和卸載七個(gè)階段浇垦。

其中加載、驗(yàn)證荣挨、準(zhǔn)備男韧、初始化朴摊、和卸載這5個(gè)階段的順序是確定的。而解析階段不一定:它在某些情況下可以在初始化階段之后再開(kāi)始此虑,這是為了支持Java的運(yùn)行時(shí)綁定甚纲。

關(guān)于初始化:JVM規(guī)范明確規(guī)定,有且只有5中情況必須執(zhí)行對(duì)類(lèi)的初始化(加載朦前、驗(yàn)證介杆、準(zhǔn)備自然再此之前要發(fā)生):
1.遇到new、getstatic韭寸、putstatic春哨、invokestatic,如果類(lèi)沒(méi)有初始化恩伺,則必須初始化赴背,這幾條指令分別是指:new新對(duì)象、讀取靜態(tài)變量晶渠、設(shè)置靜態(tài)變量凰荚,調(diào)用靜態(tài)函數(shù)。
2.使用java.lang.reflect包的方法對(duì)類(lèi)進(jìn)行反射調(diào)用時(shí)褒脯,如果類(lèi)沒(méi)初始化便瑟,則需要初始化
3.當(dāng)初始化一個(gè)類(lèi)時(shí),如果發(fā)現(xiàn)父類(lèi)沒(méi)有初始化番川,則需要先觸發(fā)父類(lèi)初始化胳徽。
4.當(dāng)虛擬機(jī)啟動(dòng)時(shí),用戶需要制定一個(gè)執(zhí)行的主類(lèi)(包含main函數(shù)的類(lèi))爽彤,虛擬機(jī)會(huì)先初始化這個(gè)類(lèi)。
5.但是用JDK1.7啟的動(dòng)態(tài)語(yǔ)言支持時(shí)缚陷,如果一個(gè)MethodHandle實(shí)例最后解析的結(jié)果是REF_getStatic适篙、REF_putStaticRef_invokeStatic的方法句柄時(shí)箫爷,并且這個(gè)方法句柄所對(duì)應(yīng)的類(lèi)沒(méi)有進(jìn)行初始化嚷节,則要先觸發(fā)其初始化。

另外要注意的是:通過(guò)子類(lèi)來(lái)引用父類(lèi)的靜態(tài)字段虎锚,不會(huì)導(dǎo)致子類(lèi)初始化

public class SuperClass{
    public static int value=123;
    static{
        System.out.printLn("SuperClass init!");
    }
}

public class SubClass extends SuperClass{
    static{
        System.out.println("SubClass init!");
    }


}

public class Test{

    public static void main(String[] args){
        System.out.println(SubClass.value);
    }
}


最后只會(huì)打恿蛱怠:SuperClass init!
對(duì)應(yīng)靜態(tài)變量,只有直接定義這個(gè)字段的類(lèi)才會(huì)被初始化窜护,因此通過(guò)子類(lèi)類(lèi)引用父類(lèi)中定義的靜態(tài)變量只會(huì)觸發(fā)父類(lèi)初始化而不會(huì)觸發(fā)子類(lèi)初始化效斑。

通過(guò)數(shù)組定義來(lái)引用類(lèi),不會(huì)觸發(fā)此類(lèi)的初始化

public class Test{

    public static void main(String[] args){
        SuperClass[] sca=new SuperClass[10];
    }
}


常量會(huì)在編譯階段存入調(diào)用者的常量池柱徙,本質(zhì)上并沒(méi)有直接引用到定義常量的類(lèi)缓屠,因此不會(huì)觸發(fā)定義常量的類(lèi)初始化奇昙,示例代碼如下:

public class ConstClass{
    public static final String HELLO_WORLD="hello world";
    static {
        System.out.println("ConstClass init!");
    }

}

public class Test{
    public static void main(String[] args){

        System.out.print(ConstClass.HELLO_WORLD);
    }


}

上面代碼不會(huì)出現(xiàn)ConstClass init!

加載

加載過(guò)程主要做以下3件事
1.通過(guò)一個(gè)類(lèi)的全限定名稱來(lái)獲取此類(lèi)的二進(jìn)制流
2.強(qiáng)這個(gè)字節(jié)流所代表的靜態(tài)存儲(chǔ)結(jié)構(gòu)轉(zhuǎn)化為方法區(qū)的運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu)
3.在內(nèi)存中生成一個(gè)代表這個(gè)類(lèi)的java.lang.Class對(duì)象,作為方法區(qū)這個(gè)類(lèi)的各種數(shù)據(jù)訪問(wèn)入口。

驗(yàn)證

這個(gè)階段主要是為了確保Class文件字節(jié)流中包含信息符合當(dāng)前虛擬機(jī)的要求敌完,并且不會(huì)出現(xiàn)危害虛擬機(jī)自身的安全储耐。

準(zhǔn)備

準(zhǔn)備階段是正式為類(lèi)變量分配內(nèi)存并設(shè)置類(lèi)變量初始值的階段,這些變量所使用的內(nèi)存都在方法區(qū)中分配滨溉。首先什湘,這個(gè)時(shí)候分配內(nèi)存僅僅包括類(lèi)變量(被static修飾的變量),而不包括實(shí)例變量晦攒。實(shí)例變量會(huì)在對(duì)象實(shí)例化時(shí)隨著對(duì)象一起分配在java堆中闽撤。其次這里所說(shuō)的初始值“通常情況下”是數(shù)據(jù)類(lèi)型的零值,假設(shè)一個(gè)類(lèi)變量定義為

public static int value=123;

那變量value在準(zhǔn)備階段后的初始值是0勤家,而不是123腹尖,因?yàn)檫€沒(méi)有執(zhí)行任何Java方法,而把value賦值為123是在程序編譯后伐脖,存放在類(lèi)構(gòu)造函數(shù)<clinit>()方法中热幔。

解析

解析階段是把虛擬機(jī)中常量池的符號(hào)引用替換為直接引用的過(guò)程。

初始化

類(lèi)初始化時(shí)類(lèi)加載的最后一步讼庇,前面類(lèi)加載過(guò)程中绎巨,除了加載階段用戶可以通過(guò)自定義類(lèi)加載器參與以外,其余動(dòng)作都是虛擬機(jī)主導(dǎo)和控制蠕啄。到了初始化階段场勤,才是真正執(zhí)行類(lèi)中定義Java程序代碼。

準(zhǔn)備階段中歼跟,變量已經(jīng)賦過(guò)一次系統(tǒng)要求的初始值和媳,而在初始化階段,根據(jù)程序員通過(guò)程序制定的主觀計(jì)劃初始化類(lèi)變量哈街。初始化過(guò)程其實(shí)是執(zhí)行類(lèi)構(gòu)造器<clinit>()方法的過(guò)程留瞳。

<clinit>()方法是由編譯器自動(dòng)收集類(lèi)中所有類(lèi)變量的賦值動(dòng)作和靜態(tài)語(yǔ)句塊中的語(yǔ)句合并產(chǎn)生的。收集的順序是按照語(yǔ)句在源文件中出現(xiàn)的順序骚秦。靜態(tài)語(yǔ)句塊中只能訪問(wèn)定義在靜態(tài)語(yǔ)句塊之前的變量她倘,定義在它之后的變量可以賦值,但不能訪問(wèn)作箍。如下所示:

public class Test{
    static{
        i=0;//給變量賦值硬梁,可以通過(guò)編譯
        System.out.print(i);//這句編譯器會(huì)提示:“非法向前引用”
    }
    static int i=1;

}

<clinit>()方法與類(lèi)構(gòu)造函數(shù)(或者說(shuō)實(shí)例構(gòu)造器<init>())不同,他不需要顯式地調(diào)用父類(lèi)構(gòu)造器胞得,虛擬機(jī)會(huì)保證子類(lèi)的<clinit>()方法執(zhí)行之前荧止,父類(lèi)的<clinit>()已經(jīng)執(zhí)行完畢。

類(lèi)加載器

關(guān)于自定義類(lèi)加載器,和雙親委派模型罩息,這里不再提嗤详,寫(xiě)了幾個(gè)小時(shí)了,該洗洗睡了~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末瓷炮,一起剝皮案震驚了整個(gè)濱河市葱色,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌娘香,老刑警劉巖苍狰,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異烘绽,居然都是意外死亡淋昭,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)安接,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)翔忽,“玉大人,你說(shuō)我怎么就攤上這事盏檐⌒剑” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵胡野,是天一觀的道長(zhǎng)材失。 經(jīng)常有香客問(wèn)我,道長(zhǎng)硫豆,這世上最難降的妖魔是什么龙巨? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮熊响,結(jié)果婚禮上旨别,老公的妹妹穿的比我還像新娘。我一直安慰自己汗茄,他們只是感情好昼榛,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著剔难,像睡著了一般。 火紅的嫁衣襯著肌膚如雪奥喻。 梳的紋絲不亂的頭發(fā)上偶宫,一...
    開(kāi)封第一講書(shū)人閱讀 49,144評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音环鲤,去河邊找鬼纯趋。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的吵冒。 我是一名探鬼主播纯命,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼惯裕,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼耍贾!你這毒婦竟也來(lái)了倔幼?” 一聲冷哼從身側(cè)響起症革,我...
    開(kāi)封第一講書(shū)人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤冕屯,失蹤者是張志新(化名)和其女友劉穎琅攘,沒(méi)想到半個(gè)月后饮潦,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體琐脏,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡南捂,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年吴裤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片溺健。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡麦牺,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出鞭缭,到底是詐尸還是另有隱情剖膳,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布缚去,位于F島的核電站潮秘,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏易结。R本人自食惡果不足惜枕荞,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望搞动。 院中可真熱鬧躏精,春花似錦、人聲如沸鹦肿。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)箩溃。三九已至瞭吃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間涣旨,已是汗流浹背歪架。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留霹陡,地道東北人和蚪。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓止状,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親攒霹。 傳聞我的和親對(duì)象是個(gè)殘疾皇子怯疤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • JVM內(nèi)存模型Java虛擬機(jī)(Java Virtual Machine=JVM)的內(nèi)存空間分為五個(gè)部分,分別是: ...
    光劍書(shū)架上的書(shū)閱讀 2,483評(píng)論 2 26
  • 一催束、運(yùn)行時(shí)數(shù)據(jù)區(qū)域 Java虛擬機(jī)管理的內(nèi)存包括幾個(gè)運(yùn)行時(shí)數(shù)據(jù)內(nèi)存:方法區(qū)集峦、虛擬機(jī)棧、本地方法棧泣崩、堆少梁、程序計(jì)數(shù)器,...
    加油小杜閱讀 1,511評(píng)論 1 15
  • 《深入理解Java虛擬機(jī)》筆記_第一遍 先取看完這本書(shū)(JVM)后必須掌握的部分矫付。 第一部分 走近 Java 從傳...
    xiaogmail閱讀 5,062評(píng)論 1 34
  • 在陰雨濛濛的早晨凯沪,我看到了遠(yuǎn)山層疊的墨色,從黑买优,灰到淺灰妨马,疊疊層層,配合著低低矮矮白墻青瓦杀赢,宛如吳冠中筆下畫(huà)般意境...
    素言簡(jiǎn)說(shuō)閱讀 319評(píng)論 0 4
  • 過(guò)去我一直都是吝于贊美他人的烘跺。 小的時(shí)候,我認(rèn)為周?chē)娜艘礇](méi)我厲害脂崔,要么我不承認(rèn)比我厲害滤淳,反正“沒(méi)有什么了不起的...
    元?dú)庑∥?/span>閱讀 419評(píng)論 0 0