深入理解JVM

之前我們文章提到過(guò)反射,說(shuō)的比較淺顯,我們這里來(lái)理解JVM直秆。

一個(gè)標(biāo)準(zhǔn)的JVM是這樣的


在這里插入圖片描述

JVM負(fù)責(zé)裝載class文件并執(zhí)行,我們首先來(lái)了解類加載和執(zhí)行的機(jī)制鞭盟。

類加載機(jī)制

JVM將.class文件加載到JVM圾结,并形成Class對(duì)象,之后就可以對(duì)Class對(duì)象進(jìn)行實(shí)例化并調(diào)用齿诉。
該過(guò)程分為三個(gè)步驟:

  1. 裝載筝野。
  2. 鏈接。
  3. 初始化粤剧。
在這里插入圖片描述

  • 裝載

負(fù)責(zé)找到二進(jìn)制字節(jié)碼并加載到JVM中歇竟。
JVM通過(guò)類的全限定名以及類加載器完成類的加載。
比如Object[] o=new Object[10]抵恋,o的全限定名:[Ljava.lang.Object焕议,并由數(shù)組型中的元素類型所在的ClassLoader進(jìn)行加載。


  • 鏈接

鏈接過(guò)程負(fù)責(zé)對(duì)二進(jìn)制字節(jié)碼進(jìn)行校驗(yàn)弧关、初始化裝載類中的靜態(tài)變量以及解析類中調(diào)用的接口盅安、類。


  • 初始化

初始化過(guò)程即執(zhí)行類中的靜態(tài)初始化代碼世囊,構(gòu)造器代碼以及靜態(tài)屬性的初始化别瞭。

類執(zhí)行機(jī)制

在完成將class文件信息加載到JVM并產(chǎn)生Class對(duì)象后,就可執(zhí)行Class對(duì)象的靜態(tài)方法或?qū)嵗瘜?duì)象進(jìn)行調(diào)用了株憾。在源碼編譯階段蝙寨,將源碼編譯為JVM字節(jié)碼,JVM字節(jié)碼是一種中間代碼的方式嗤瞎,要由JVM在運(yùn)行期間對(duì)其進(jìn)行解釋并執(zhí)行籽慢。這種方式稱為:字節(jié)碼解釋執(zhí)行方式。

字節(jié)碼解釋執(zhí)行

由于采用JVM字節(jié)碼猫胁,也就是說(shuō)JVM有一套自己的指令來(lái)執(zhí)行中間碼:

  • invokestatic
    調(diào)用static方法
  • invokevirtual
    調(diào)用對(duì)象實(shí)例的方法
  • invokeinterface
    調(diào)用接口
  • invokespecial
    調(diào)用private方法和<init>對(duì)象初始化方法

比如下面這一段代碼:

public class Demo{
    public void execute(){
        A.execute();
        A a=new A();
        a.bar();
        IFoo b=new B();
        b.bar();
    }
}
class A{
    public static int execute(){
        return 1+2;
    }
    public int bar(){
        return 1+2;
    }
}
class B implements IFoo{
    public int bar(){
        return 1+2;
    }
}
public interface IFoo{
    public int bar();
}

通過(guò)javac 編譯上面的代碼后箱亿,使用javap -c Demo 查看其execute方法的字節(jié)碼:

Compiled from "Demo.java"
public class Demo {
  public Demo();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public void execute();
    Code:
       0: invokestatic  #2                  // Method A.execute:()I
       3: pop
       4: new           #3                  // class A
       7: dup
       8: invokespecial #4                  // Method A."<init>":()V
      11: astore_1
      12: aload_1
      13: invokevirtual #5                  // Method A.bar:()I
      16: pop
      17: new           #6                  // class B
      20: dup
      21: invokespecial #7                  // Method B."<init>":()V
      24: astore_2
      25: aload_2
      26: invokeinterface #8,  1            // InterfaceMethod IFoo.bar:()I
      31: pop
      32: return
}

從上面的栗子可以看出,四種指令對(duì)應(yīng)調(diào)用方法的情況弃秆。
Sun JDK基于棧的體系結(jié)構(gòu)來(lái)執(zhí)行字節(jié)碼届惋,基于棧方式的好處就是代碼緊湊,體積小菠赚。

線程在創(chuàng)建后脑豹,都會(huì)產(chǎn)生程序計(jì)數(shù)器(PC或者稱為PC registers)和棧(Stack);PC存放了下一條要執(zhí)行的指令在方法內(nèi)的偏移量衡查;棧中存放了棧幀(StackFrame)瘩欺,每個(gè)方法每次調(diào)用都會(huì)產(chǎn)生棧幀,棧幀主要分為局部變量區(qū)和操作數(shù)棧兩個(gè)部分,局部變量區(qū)用于存放方法體中的局部變量和參數(shù)俱饿,操作數(shù)棧中用于存放方法執(zhí)行過(guò)程中產(chǎn)生的中間結(jié)果歌粥,棧幀中還有一些其他空間,例如只想方法已解析的常量池的引用拍埠、其他一些VM內(nèi)部需要的數(shù)據(jù)等失驶,具體結(jié)構(gòu)如下圖所示:

在這里插入圖片描述

下面來(lái)看一個(gè)方法執(zhí)行時(shí)過(guò)程的栗子:

public class Demo2{
    public static void foo(){
        int a=1;
        int b=2;
        int c=(a+b)*5;
    }
}

同樣的方法獲得JVM字節(jié)碼:

 public class Demo2 {
  public Demo2();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void foo();
    Code:
       0: iconst_1
       1: istore_0
       2: iconst_2
       3: istore_1
       4: iload_0
       5: iload_1
       6: iadd
       7: iconst_5
       8: imul
       9: istore_2
      10: return
}

每條字節(jié)碼及其對(duì)應(yīng)的解釋如下:


在這里插入圖片描述

對(duì)于方法的指令解釋執(zhí)行,執(zhí)行方式為經(jīng)典馮諾伊曼體系中的FDX循環(huán)方式枣购,即獲取下一條指令嬉探,解碼并分派,然后執(zhí)行棉圈。在實(shí)現(xiàn)FDX循環(huán)時(shí)有switch-threading涩堤、token-threading、direct-threading等多種方式分瘾。

第一種swith-threading胎围,代碼大致如下:

while(true){
    int code=fetchNextCode();//下一條指令
    switch(code){
        case IADD: //do add
        case ...: //do sth
    }
}

每次執(zhí)行完都得重新回到循環(huán)開(kāi)始點(diǎn),然后重新獲取下一條指令芹敌,并繼續(xù)switch痊远,這導(dǎo)致了大部分時(shí)間都花在了跳轉(zhuǎn)和獲取下一條指令上垮抗,真的的業(yè)務(wù)邏輯代碼非常短氏捞。

token-threading在上面的基礎(chǔ)上稍微有所修改:

IADD:{
    //do add
    fetchNextCode();//下一條指令
    dispatch();
}
ICONST_0:{
    push(0);
    fetchNextCode();下一條指令
    dispatch();
}
...

該方法相對(duì)第一種switch-threading而言,冗余了fetch next code和dispatch冒版,相對(duì)比較消耗內(nèi)存液茎,但是由于去除了switch,因此性能會(huì)稍微好一些辞嗡。
其他的xxx-threading做了更多的優(yōu)化捆等,在此不做贅述。Sun JDK的重點(diǎn)為編譯成機(jī)器碼续室,并沒(méi)有在解釋器上做太復(fù)雜的處理栋烤,因此采用了token-threading方法,為了讓解釋執(zhí)行能夠更加高效挺狰,Sun JDK還做了一些其他的優(yōu)化明郭,主要是:棧頂緩存(top-of-stack caching)部分棧幀共享

棧頂緩存
在方法執(zhí)行過(guò)程中丰泊,可以看到有很多操作要將值放入操作數(shù)棧薯定,這導(dǎo)致了寄存器和內(nèi)存要不斷的交換數(shù)據(jù),Sun JDK采用了一個(gè)棧頂緩存瞳购,即將本來(lái)位于操作數(shù)棧頂?shù)闹抵苯泳彺娴郊拇嫫魃匣爸叮芍苯釉诩拇嫫饔?jì)算,然后放回操作數(shù)棧。

部分棧幀共享
當(dāng)一個(gè)方法調(diào)用另一個(gè)方法時(shí)年堆,通常傳入另一個(gè)方法的參數(shù)為已存放在操作數(shù)棧的數(shù)據(jù)吞杭,Sun JDK采用:當(dāng)調(diào)用方法時(shí),后一個(gè)方法將前一個(gè)方法的操作數(shù)棧作為當(dāng)前方法的局部變量嘀韧,從而節(jié)省數(shù)據(jù)copy帶來(lái)的消耗篇亭。

(運(yùn)行時(shí))編譯執(zhí)行

由于解釋執(zhí)行的效率太低,Sun JDK提供將字節(jié)碼編譯為機(jī)器碼锄贷,在執(zhí)行過(guò)程中译蒂,對(duì)執(zhí)行頻率高的代碼進(jìn)行編譯執(zhí)行,對(duì)執(zhí)行不頻繁的代碼采用解釋執(zhí)行谊却,因此Sun JDK也稱為Hotspot VM柔昼,在編譯上Sun JDK提供了兩種模式,client compiler(-client) 和 server compiler(-server)炎辨。


  • client compiler

client compiler比較輕量級(jí)捕透,制作少量性能開(kāi)銷比較高的優(yōu)化,它占用內(nèi)存較少碴萧,適合于桌面交互式應(yīng)用乙嘀,主要的優(yōu)化有:方法內(nèi)聯(lián)、去虛擬化破喻、冗余消除等虎谢。
1.方法內(nèi)聯(lián)
例如這樣一段代碼:

public void bar(){
    ...
    bar2();
    ...
}
public void bar2(){
    //bar2執(zhí)行代碼
}

當(dāng)編譯時(shí),如果bar2代碼編譯后的字節(jié)數(shù)小雨等于35個(gè)字節(jié)(可以通過(guò)啟動(dòng)參數(shù)-XX:MaxInlineSize=35來(lái)控制)曹质,那么會(huì)演變稱為這樣的結(jié)構(gòu):

public void bar(){
    ...
    //bar2執(zhí)行代碼
    ...
}

可在debug版本的JDK的啟動(dòng)參數(shù)上加上-XX:+PrintInlining來(lái)查看方法內(nèi)聯(lián)信息婴噩。

2.去虛擬化
去虛擬化是指在裝載class文件后,進(jìn)行類層次的分析羽德,如發(fā)現(xiàn)類中的方法只提供一個(gè)實(shí)現(xiàn)類几莽,那么對(duì)于調(diào)用了此方法的代碼,也可進(jìn)行方法內(nèi)聯(lián)宅静,從而提升執(zhí)行的性能章蚣。

例如這樣的代碼:

public interface IFoo{
    public void bar();
}
public class Foo implements IFoo{
    public void bar(){
        //Foo bar method
    }
}
public class Demo{
    public void execute(IFoo foo){
        foo.bar();
    }
}

當(dāng)整個(gè)JVM只有Foo實(shí)現(xiàn)了IFoo接口,Demo execute方法被編譯的時(shí)候姨夹,就會(huì)演變成類似這樣的結(jié)構(gòu):

public void execute(){
    //Foo bar method
}

3.冗余消除
冗余消除是指在編譯時(shí)纤垂,根據(jù)運(yùn)行時(shí)狀況進(jìn)行折疊或消除代碼。
比如:

private static final Log=log.LogFactory.getLog("BLUEDAVY")匀伏;
private static final boolean isDebug=log.isDebugEnabled();
public void execute(){
    if(isDebug){
        log.debug(xxx);
    }
    //do something else
}

如果boolean值是false那么會(huì)演變?yōu)槿缦碌慕Y(jié)構(gòu):

public void execute(){
    //do something else
}

  • server compiler

server compiler較為重量級(jí)洒忧,采用了大量傳統(tǒng)編譯優(yōu)化技巧,占用內(nèi)存相對(duì)較多够颠,適合服務(wù)端的應(yīng)用熙侍,下面介紹幾個(gè)優(yōu)化:

1.標(biāo)量替換
例如:

Point p=new Point(1,2);
sout("point.x="+p.x+";point.y="+p.y);

當(dāng)p對(duì)象在后面沒(méi)用到的時(shí)候,會(huì)演變成下面的結(jié)構(gòu):

int x=1;
int y=2;
sout("point.x="+x+";point.y="+y);

2.同步消除
如果發(fā)現(xiàn)同步的對(duì)象沒(méi)必要,那么會(huì)直接去掉:

Point p=new Point();
sysnchronized(p){
    //do something
}

演變?yōu)椋?/p>

Point p=new Point();
//do somehing





從上面兩種重量級(jí)和輕量級(jí)的編譯來(lái)看蛉抓,它們做了很多努力來(lái)優(yōu)化庆尘。為什么不再一開(kāi)始就編譯稱為機(jī)器碼呢?
主要有下面幾方面的原因:

  1. 靜態(tài)編譯并不能根據(jù)程序的運(yùn)行狀況來(lái)優(yōu)化執(zhí)行的代碼巷送,server compiler收集運(yùn)行數(shù)據(jù)越長(zhǎng)驶忌,編譯出來(lái)的代碼會(huì)越優(yōu)化。
  2. 解釋執(zhí)行比編譯執(zhí)行更省內(nèi)存笑跛。
  3. 啟動(dòng)時(shí)解釋執(zhí)行的啟動(dòng)速度比編譯后再啟動(dòng)更快付魔。

那么什么時(shí)候就需要編譯呢?這需要一個(gè)權(quán)衡值飞蹂,Sun JDK有兩個(gè)計(jì)數(shù)器來(lái)計(jì)算閾值:

  • CompileThreshold
    當(dāng)方法被調(diào)用多少次后几苍,編譯為機(jī)器碼。通過(guò)-XX:CompileThreshold=10000來(lái)設(shè)置該值陈哑。client默認(rèn)1500次妻坝,server默認(rèn)10000;
  • OnStackReplacePercentage
    棧上替換的百分比惊窖,該值用于/參與計(jì)算是否觸發(fā)OSR編譯的閾值刽宪,通過(guò)-XX:OnStackReplacePercentage=140來(lái)設(shè)置。在client模式下界酒,計(jì)算規(guī)則為:CompileThreshold * (OnStackReplacePercentage/100)圣拄;在server模式下,計(jì)算規(guī)則為:(OnStackReplacePercentage – InterpreterProfilePercentage))/100

反射執(zhí)行

反射執(zhí)行是基于反射來(lái)動(dòng)態(tài)調(diào)用某對(duì)象實(shí)例中對(duì)應(yīng)的方法盾计,訪問(wèn)查看對(duì)象的屬性等等售担,之前的文章寫的很清楚赁遗。
Java中通過(guò)如下的方法調(diào)用:

Class actionClass=Class.forName(外部實(shí)現(xiàn)類);
Method method=actionClass.getMethod(“execute”,null);
Object action=actionClass.newInstance();
method.invoke(action,null);

這樣在創(chuàng)建對(duì)象過(guò)程和方法調(diào)用過(guò)程是動(dòng)態(tài)的署辉,具有很高的靈活性。

內(nèi)存回收

內(nèi)存空間

Sun JDK在實(shí)現(xiàn)時(shí)岩四,將內(nèi)存空間劃分為方法區(qū)哭尝、堆、本地方法棧剖煌、PC寄存器以及JVM方法棧材鹦。如下圖所示:


在這里插入圖片描述

  • 方法區(qū)

方法區(qū)存放了要加載的類的信息、靜態(tài)變量耕姊、final類型常量等信息桶唐。方法區(qū)是全局共享的。
通過(guò)-XX:PermSize和-XX:MaxPermSize來(lái)指定最小最大的值茉兰,保證方法區(qū)內(nèi)存大小尤泽。


堆用于存儲(chǔ)對(duì)象實(shí)例及數(shù)組值,可以認(rèn)為Java中所有new的對(duì)象都在此分配。


  • 本地方法棧

用于支持native方法的執(zhí)行坯约。在Sun JDK的實(shí)現(xiàn)中本地方法棧和JVM方法棧是同一個(gè)熊咽。


  • PC寄存器和JVM方法棧

每個(gè)線程單獨(dú)創(chuàng)建自己的PC寄存器和JVM方法棧(私有的)。當(dāng)方法運(yùn)行完畢時(shí)闹丐,其對(duì)應(yīng)的棧幀所用內(nèi)存也會(huì)自動(dòng)釋放横殴。

收集器

JVM通過(guò)GC來(lái)回收堆和方法區(qū)中的內(nèi)存,GC的基本原理是首先找到程序中不再被使用的對(duì)象卿拴,然后回收這些對(duì)象所占用的內(nèi)存衫仑。
主要的收集器有引用計(jì)數(shù)收集器跟蹤收集器

  1. 引用計(jì)數(shù)收集器
    顧名思義堕花,通過(guò)計(jì)數(shù)器記錄對(duì)象引用數(shù)目惑畴,當(dāng)引用數(shù)目為0時(shí)回收對(duì)象。
  2. 跟蹤收集器
    跟蹤收集器采用的為集中式的管理方式航徙,全局記錄數(shù)據(jù)的引用狀態(tài)如贷。基于一定條件觸發(fā)(例如定時(shí)觸發(fā)或者空間不足時(shí)觸發(fā))到踏,執(zhí)行時(shí)需要從根集合來(lái)掃描對(duì)象的引用關(guān)系杠袱,這可能會(huì)造成應(yīng)用程序暫停,主要有復(fù)制窝稿、標(biāo)記-清除楣富、標(biāo)記-壓縮三種實(shí)現(xiàn)算法。
    (其實(shí)就是清理內(nèi)存的算法伴榔,計(jì)算機(jī)原理也學(xué)過(guò))
    復(fù)制:從根集合中掃描存活的對(duì)象纹蝴,復(fù)制到未使用的空間中。


    在這里插入圖片描述

    標(biāo)記清除:從根集合中掃描踪少,對(duì)存活的對(duì)象標(biāo)記塘安,然后再掃描整個(gè)空間中未標(biāo)記的對(duì)象,進(jìn)行回收援奢。


    在這里插入圖片描述

    標(biāo)記壓縮:和標(biāo)記清除一樣也要進(jìn)行標(biāo)記兼犯,不過(guò)第二步在回收不存活的對(duì)象的內(nèi)存后,會(huì)將對(duì)象左移壓縮集漾。
    在這里插入圖片描述

Sun JDK可用的GC

以上三種跟蹤收集器各有優(yōu)缺點(diǎn)切黔,Sun JDK認(rèn)為:程序中大部分對(duì)象存活時(shí)間都是較短的,只有少部分是長(zhǎng)期存活的具篇。根據(jù)這一分析纬霞,JVM被劃分為新生代和舊生代,根據(jù)兩代generation有不同的GC實(shí)現(xiàn)驱显。

在這里插入圖片描述

新生代中對(duì)象存活期短诗芜,因此選用復(fù)制算法進(jìn)行回收侨舆。由于在復(fù)制的時(shí)候,需要一塊未使用的空間來(lái)存放存活的對(duì)象(和固態(tài)硬盤一樣绢陌,也是要預(yù)留空間)挨下,所以新生代又被分為Eden、S0脐湾、S1三塊空間臭笆。
Eden Space存放新創(chuàng)建的對(duì)象,S0或S1其中一塊作為復(fù)制的目標(biāo)空間(輪流):當(dāng)一塊作為復(fù)制的目標(biāo)空間秤掌,另一塊被清空愁铺。因此S0和S1也被稱為:From Space和To Space。

Sun JDK提供了串行GC闻鉴、并行回收GC和并行GC三種方式來(lái)回收茵乱,在此不做贅述。

舊生代與新生代不同孟岛,對(duì)象存活的時(shí)間比較長(zhǎng)瓶竭,比較穩(wěn)定,因此采用標(biāo)記(Mark)算法來(lái)進(jìn)行回收渠羞,所謂標(biāo)記就是掃描出存活的對(duì)象斤贰,然后再進(jìn)行回收未被標(biāo)記的對(duì)象,回收后對(duì)用空出的空間要么進(jìn)行合并次询,要么標(biāo)記出來(lái)便于下次進(jìn)行分配荧恍,總之就是要減少內(nèi)存碎片帶來(lái)的效率損耗。在執(zhí)行機(jī)制上JVM提供了串行 GC(SerialMSC)屯吊、并行GC(parallelMSC)和并發(fā)GC(CMS)送巡,具體算法細(xì)節(jié)還有待進(jìn)一步深入研究。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末盒卸,一起剝皮案震驚了整個(gè)濱河市骗爆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌世落,老刑警劉巖淮腾,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件糟需,死亡現(xiàn)場(chǎng)離奇詭異屉佳,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)洲押,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門武花,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人杈帐,你說(shuō)我怎么就攤上這事体箕∽ǘぃ” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵累铅,是天一觀的道長(zhǎng)跃须。 經(jīng)常有香客問(wèn)我,道長(zhǎng)娃兽,這世上最難降的妖魔是什么菇民? 我笑而不...
    開(kāi)封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮投储,結(jié)果婚禮上第练,老公的妹妹穿的比我還像新娘。我一直安慰自己玛荞,他們只是感情好娇掏,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著勋眯,像睡著了一般婴梧。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上客蹋,一...
    開(kāi)封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天志秃,我揣著相機(jī)與錄音,去河邊找鬼嚼酝。 笑死浮还,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的闽巩。 我是一名探鬼主播钧舌,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼涎跨!你這毒婦竟也來(lái)了洼冻?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤隅很,失蹤者是張志新(化名)和其女友劉穎撞牢,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體叔营,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡屋彪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了绒尊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片畜挥。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖婴谱,靈堂內(nèi)的尸體忽然破棺而出蟹但,到底是詐尸還是另有隱情躯泰,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布华糖,位于F島的核電站麦向,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏客叉。R本人自食惡果不足惜磕蛇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望十办。 院中可真熱鬧秀撇,春花似錦、人聲如沸向族。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)件相。三九已至再扭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間夜矗,已是汗流浹背泛范。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留紊撕,地道東北人罢荡。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像对扶,于是被迫代替她去往敵國(guó)和親区赵。 傳聞我的和親對(duì)象是個(gè)殘疾皇子峭梳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354