java8 去除 永久代

在過去(當(dāng)自定義類加載器使用不普遍的時(shí)候)点楼,類幾乎是“靜態(tài)的”并且很少被卸載和回收,因此類也可以被看成“永久的”卸夕。另外由于類作為JVM實(shí)現(xiàn)的一部分柱告,它們不由程序來創(chuàng)建截驮,因?yàn)樗鼈円脖徽J(rèn)為是“非堆”的內(nèi)存。

在JDK8之前的HotSpot虛擬機(jī)中末荐,類的這些“永久的”數(shù)據(jù)存放在一個(gè)叫做永久代的區(qū)域侧纯。永久代一段連續(xù)的內(nèi)存空間,我們在JVM啟動(dòng)之前可以通過設(shè)置-XX:MaxPermSize的值來控制永久代的大小甲脏,32位機(jī)器默認(rèn)的永久代的大小為64M眶熬,64位的機(jī)器則為85M妹笆。永久代的垃圾回收和老年代的垃圾回收是綁定的,一旦其中一個(gè)區(qū)域被占滿娜氏,這兩個(gè)區(qū)都要進(jìn)行垃圾回收拳缠。但是有一個(gè)明顯的問題,由于我們可以通過?XX:MaxPermSize 設(shè)置永久代的大小贸弥,一旦類的元數(shù)據(jù)超過了設(shè)定的大小窟坐,程序就會耗盡內(nèi)存,并出現(xiàn)內(nèi)存溢出錯(cuò)誤(OOM)绵疲。

備注:在JDK7之前的HotSpot虛擬機(jī)中哲鸳,納入字符串常量池的字符串被存儲在永久代中,因此導(dǎo)致了一系列的性能問題和內(nèi)存溢出錯(cuò)誤盔憨。

這邊轉(zhuǎn)自? http://www.cnblogs.com/moonandstar08/p/5001914.html

這項(xiàng)改動(dòng)是很有必要的徙菠,因?yàn)閷τ谰么M(jìn)行調(diào)優(yōu)是很困難的。永久代中的元數(shù)據(jù)可能會隨著每一次Full GC發(fā)生而進(jìn)行移動(dòng)郁岩。并且為永久代設(shè)置空間大小也是很難確定的婿奔,因?yàn)檫@其中有很多影響因素,比如類的總數(shù)问慎,常量池的大小和方法數(shù)量等萍摊。

同時(shí),HotSpot虛擬機(jī)的每種類型的垃圾回收器都需要特殊處理永久代中的元數(shù)據(jù)如叼。將元數(shù)據(jù)從永久代剝離出來冰木,不僅實(shí)現(xiàn)了對元空間的無縫管理,還可以簡化Full GC以及對以后的并發(fā)隔離類元數(shù)據(jù)等方面進(jìn)行優(yōu)化薇正。

新增加的metaspace:

持久代的空間被徹底地刪除了片酝,它被一個(gè)叫元空間的區(qū)域所替代了囚衔。持久代刪除了之后挖腰,很明顯,JVM會忽略PermSize和MaxPermSize這兩個(gè)參數(shù)练湿,還有就是你再也看不到j(luò)ava.lang.OutOfMemoryError: PermGen error的異常了猴仑。

JDK 8的HotSpot JVM現(xiàn)在使用的是本地內(nèi)存來表示類的元數(shù)據(jù),這個(gè)區(qū)域就叫做元空間肥哎。

元空間的特點(diǎn):

充分利用了Java語言規(guī)范中的好處:類及相關(guān)的元數(shù)據(jù)的生命周期與類加載器的一致辽俗。

每個(gè)加載器有專門的存儲空間

只進(jìn)行線性分配

不會單獨(dú)回收某個(gè)類

省掉了GC掃描及壓縮的時(shí)間

元空間里的對象的位置是固定的

如果GC發(fā)現(xiàn)某個(gè)類加載器不再存活了,會把相關(guān)的空間整個(gè)回收掉

元空間的內(nèi)存分配模型

絕大多數(shù)的類元數(shù)據(jù)的空間都從本地內(nèi)存中分配

用來描述類元數(shù)據(jù)的類也被刪除了

分元數(shù)據(jù)分配了多個(gè)虛擬內(nèi)存空間

給每個(gè)類加載器分配一個(gè)內(nèi)存塊的列表篡诽。塊的大小取決于類加載器的類型; sun/反射/代理對應(yīng)的類加載器的塊會小一些

歸還內(nèi)存塊崖飘,釋放內(nèi)存塊列表

一旦元空間的數(shù)據(jù)被清空了,虛擬內(nèi)存的空間會被回收掉

減少碎片的策略

我們來看下JVM是如何給元數(shù)據(jù)分配虛擬內(nèi)存的空間的

你可以看到虛擬內(nèi)存空間是如何分配的(vs1,vs2,vs3) 杈女,以及類加載器的內(nèi)存塊是如何分配的朱浴。CL是Class Loader的縮寫吊圾。

理解_mark和_klass指針

要想理解下面這張圖,你得搞清楚這些指針都是什么東西翰蠢。

JVM中项乒,每個(gè)對象都有一個(gè)指向它自身類的指針,不過這個(gè)指針只是指向具體的實(shí)現(xiàn)類梁沧,而不是接口或者抽象類檀何。

對于32位的JVM:

_mark : 4字節(jié)常量

_klass: 指向類的4字節(jié)指針 對象的內(nèi)存布局中的第二個(gè)字段( _klass,在32位JVM中廷支,相對對象在內(nèi)存中的位置的偏移量是4频鉴,64位的是8)指向的是內(nèi)存中對象的類定義。

64位的JVM:

_mark : 8字節(jié)常量

_klass: 指向類的8字節(jié)的指針

開啟了指針壓縮的64位JVM: _mark : 8字節(jié)常量

_klass: 指向類的4字節(jié)的指針

Java對象的內(nèi)存布局

類指針壓縮空間(Compressed Class Pointer Space)

只有是64位平臺上啟用了類指針壓縮才會存在這個(gè)區(qū)域恋拍。對于64位平臺砚殿,為了壓縮JVM對象中的_klass指針的大小,引入了類指針壓縮空間(Compressed Class Pointer Space)芝囤。

壓縮指針后的內(nèi)存布局

指針壓縮概要

64位平臺上默認(rèn)打開

使用-XX:+UseCompressedOops壓縮對象指針 "oops"指的是普通對象指針("ordinary" object pointers)似炎。 Java堆中對象指針會被壓縮成32位。 使用堆基地址(如果堆在低26G內(nèi)存中的話悯姊,基地址為0)

使用-XX:+UseCompressedClassPointers選項(xiàng)來壓縮類指針

對象中指向類元數(shù)據(jù)的指針會被壓縮成32位

類指針壓縮空間會有一個(gè)基地址

元空間和類指針壓縮空間的區(qū)別

類指針壓縮空間只包含類的元數(shù)據(jù)羡藐,比如InstanceKlass, ArrayKlass 僅當(dāng)打開了UseCompressedClassPointers選項(xiàng)才生效 為了提高性能,Java中的虛方法表也存放到這里 這里到底存放哪些元數(shù)據(jù)的類型悯许,目前仍在減少

元空間包含類的其它比較大的元數(shù)據(jù)仆嗦,比如方法,字節(jié)碼先壕,常量池等瘩扼。

元空間的調(diào)優(yōu)

使用-XX:MaxMetaspaceSize參數(shù)可以設(shè)置元空間的最大值,默認(rèn)是沒有上限的垃僚,也就是說你的系統(tǒng)內(nèi)存上限是多少它就是多少集绰。-XX:MetaspaceSize選項(xiàng)指定的是元空間的初始大小,如果沒有指定的話谆棺,元空間會根據(jù)應(yīng)用程序運(yùn)行時(shí)的需要?jiǎng)討B(tài)地調(diào)整大小栽燕。

MaxMetaspaceSize的調(diào)優(yōu)

-XX:MaxMetaspaceSize={unlimited}

元空間的大小受限于你機(jī)器的內(nèi)存

限制類的元數(shù)據(jù)使用的內(nèi)存大小,以免出現(xiàn)虛擬內(nèi)存切換以及本地內(nèi)存分配失敗改淑。如果懷疑有類加載器出現(xiàn)泄露碍岔,應(yīng)當(dāng)使用這個(gè)參數(shù);32位機(jī)器上朵夏,如果地址空間可能會被耗盡蔼啦,也應(yīng)當(dāng)設(shè)置這個(gè)參數(shù)。

元空間的初始大小是21M——這是GC的初始的高水位線仰猖,超過這個(gè)大小會進(jìn)行Full GC來進(jìn)行類的回收捏肢。

如果啟動(dòng)后GC過于頻繁掠河,請將該值設(shè)置得大一些

可以設(shè)置成和持久代一樣的大小,以便推遲GC的執(zhí)行時(shí)間

CompressedClassSpaceSize的調(diào)優(yōu)

只有當(dāng)-XX:+UseCompressedClassPointers開啟了才有效

-XX:CompressedClassSpaceSize=1G

由于這個(gè)大小在啟動(dòng)的時(shí)候就固定了的猛计,因此最好設(shè)置得大點(diǎn)唠摹。

沒有使用到的話不要進(jìn)行設(shè)置

JVM后續(xù)可能會讓這個(gè)區(qū)可以動(dòng)態(tài)的增長。不需要是連續(xù)的區(qū)域奉瘤,只要從基地址可達(dá)就行勾拉;可能會將更多的類元信息放回到元空間中;未來會基于PredictedLoadedClassCount的值來自動(dòng)的設(shè)置該空間的大小

元空間的一些工具

jmap -permstat改成了jmap -clstats盗温。它用來打印Java堆的類加載器的統(tǒng)計(jì)數(shù)據(jù)藕赞。對每一個(gè)類加載器,會輸出它的名字卖局,是否存活斧蜕,地址,父類加載器砚偶,以及它已經(jīng)加載的類的數(shù)量及大小批销。除此之外,駐留的字符串(intern)的數(shù)量及大小也會打印出來染坯。

jstat -gc均芽,這個(gè)命令輸出的是元空間的信息而非持久代的

jcmd GC.class_stats提供類元數(shù)據(jù)大小的詳細(xì)信息。使用這個(gè)功能啟動(dòng)程序時(shí)需要加上-XX:+UnlockDiagnosticVMOptions選項(xiàng)单鹿。

提高GC的性能

如果你理解了元空間的概念掀宋,很容易發(fā)現(xiàn)GC的性能得到了提升。

Full GC中仲锄,元數(shù)據(jù)指向元數(shù)據(jù)的那些指針都不用再掃描了劲妙。很多復(fù)雜的元數(shù)據(jù)掃描的代碼(尤其是CMS里面的那些)都刪除了。

元空間只有少量的指針指向Java堆儒喊。這包括:類的元數(shù)據(jù)中指向java/lang/Class實(shí)例的指針;數(shù)組類的元數(shù)據(jù)中镣奋,指向java/lang/Class集合的指針。

沒有元數(shù)據(jù)壓縮的開銷

減少了根對象的掃描(不再掃描虛擬機(jī)里面的已加載類的字典以及其它的內(nèi)部哈希表)

減少了Full GC的時(shí)間

G1回收器中澄惊,并發(fā)標(biāo)記階段完成后可以進(jìn)行類的卸載

java8中metaspace總結(jié)如下:

PermGen 空間的狀況

這部分內(nèi)存空間將全部移除唆途。

JVM的參數(shù):PermSize 和 MaxPermSize 會被忽略并給出警告(如果在啟用時(shí)設(shè)置了這兩個(gè)參數(shù))富雅。

Metaspace 內(nèi)存分配模型

大部分類元數(shù)據(jù)都在本地內(nèi)存中分配掸驱。

用于描述類元數(shù)據(jù)的“klasses”已經(jīng)被移除。

Metaspace 容量

默認(rèn)情況下没佑,類元數(shù)據(jù)只受可用的本地內(nèi)存限制(容量取決于是32位或是64位操作系統(tǒng)的可用虛擬內(nèi)存大斜显簟)。

新參數(shù)(MaxMetaspaceSize)用于限制本地內(nèi)存分配給類元數(shù)據(jù)的大小蛤奢。如果沒有指定這個(gè)參數(shù)鬼癣,元空間會在運(yùn)行時(shí)根據(jù)需要?jiǎng)討B(tài)調(diào)整陶贼。

Metaspace 垃圾回收

對于僵死的類及類加載器的垃圾回收將在元數(shù)據(jù)使用達(dá)到“MaxMetaspaceSize”參數(shù)的設(shè)定值時(shí)進(jìn)行。

適時(shí)地監(jiān)控和調(diào)整元空間對于減小垃圾回收頻率和減少延時(shí)是很有必要的待秃。持續(xù)的元空間垃圾回收說明拜秧,可能存在類、類加載器導(dǎo)致的內(nèi)存泄漏或是大小設(shè)置不合適章郁。

Java 堆內(nèi)存的影響

一些雜項(xiàng)數(shù)據(jù)已經(jīng)移到Java堆空間中枉氮。升級到JDK8之后,會發(fā)現(xiàn)Java堆 空間有所增長暖庄。

Metaspace 監(jiān)控

元空間的使用情況可以從HotSpot1.8的詳細(xì)GC日志輸出中得到聊替。

Jstat 和 JVisualVM兩個(gè)工具,在使用b75版本進(jìn)行測試時(shí)培廓,已經(jīng)更新了惹悄,但是還是能看到老的PermGen空間的出現(xiàn)。

前面已經(jīng)從理論上充分說明肩钠,下面讓我們通過“泄漏”程序進(jìn)行新內(nèi)存空間的觀察……

PermGen vs. Metaspace 運(yùn)行時(shí)比較

為了更好地理解Metaspace內(nèi)存空間的運(yùn)行時(shí)行為泣港,

將進(jìn)行以下幾種場景的測試:

使用JDK1.7運(yùn)行Java程序,監(jiān)控并耗盡默認(rèn)設(shè)定的85MB大小的PermGen內(nèi)存空間价匠。

使用JDK1.8運(yùn)行Java程序爷速,監(jiān)控新Metaspace內(nèi)存空間的動(dòng)態(tài)增長和垃圾回收過程。

使用JDK1.8運(yùn)行Java程序霞怀,模擬耗盡通過“MaxMetaspaceSize”參數(shù)設(shè)定的128MB大小的Metaspace內(nèi)存空間惫东。

首先建立了一個(gè)模擬PermGen OOM的代碼

publicclassClassA?{

publicvoidmethod(String?name)?{

//?do?nothing

}

}

上面是一個(gè)簡單的ClassA,把他編譯成class字節(jié)碼放到D:/classes下面毙石,測試代碼中用URLClassLoader來加載此類型上面類編譯成class

/**

*?模擬PermGen?OOM

*?@author?benhail

*/

publicclassOOMTest?{

publicstaticvoidmain(String[]?args)?{

try{

//準(zhǔn)備url

URL?url?=newFile("D:/classes").toURI().toURL();

URL[]?urls?=?{url};

//獲取有關(guān)類型加載的JMX接口

ClassLoadingMXBean?loadingBean?=?ManagementFactory.getClassLoadingMXBean();

//用于緩存類加載器

List?classLoaders?=newArrayList();

while(true)?{

//加載類型并緩存類加載器實(shí)例

ClassLoader?classLoader?=newURLClassLoader(urls);

classLoaders.add(classLoader);

classLoader.loadClass("ClassA");

//顯示數(shù)量信息(共加載過的類型數(shù)目廉沮,當(dāng)前還有效的類型數(shù)目,已經(jīng)被卸載的類型數(shù)目)

System.out.println("total:?"+?loadingBean.getTotalLoadedClassCount());

System.out.println("active:?"+?loadingBean.getLoadedClassCount());

System.out.println("unloaded:?"+?loadingBean.getUnloadedClassCount());

}

}catch(Exception?e)?{

e.printStackTrace();

}

}

}

虛擬機(jī)器參數(shù)設(shè)置如下:-verbose -verbose:gc

設(shè)置-verbose參數(shù)是為了獲取類型加載和卸載的信息

設(shè)置-verbose:gc是為了獲取垃圾收集的相關(guān)信息

JDK 1.7 @64-bit – PermGen 耗盡測試

Java1.7的PermGen默認(rèn)空間為85 MB(或者可以通過-XX:MaxPermSize=XXXm指定)

可以從上面的JVisualVM的截圖看出:當(dāng)加載超過6萬個(gè)類之后徐矩,PermGen被耗盡滞时。我們也能通過程序和GC的輸出觀察耗盡的過程。

程序輸出(摘取了部分)

......

[Loaded?ClassA?from?file:/D:/classes/]

total:64887

active:64887

unloaded:0

[GC?245041K->213978K(536768K),0.0597188secs]

[Full?GC?213978K->211425K(644992K),0.6456638secs]

[GC?211425K->211425K(656448K),0.0086696secs]

[Full?GC?211425K->211411K(731008K),0.6924754secs]

[GC?211411K->211411K(726528K),0.0088992secs]

...............

java.lang.OutOfMemoryError:?PermGen?space

JDK 1.8 @64-bit – Metaspace大小動(dòng)態(tài)調(diào)整測試

Java的Metaspace空間:不受限制 (默認(rèn))

從上面的截圖可以看到滤灯,JVM Metaspace進(jìn)行了動(dòng)態(tài)擴(kuò)展坪稽,本地內(nèi)存的使用由20MB增長到646MB,以滿足程序中不斷增長的類數(shù)據(jù)內(nèi)存占用需求鳞骤。我們也能觀察到JVM的垃圾回收事件—試圖銷毀僵死的類或類加載器對象窒百。但是,由于我們程序的泄漏豫尽,JVM別無選擇只能動(dòng)態(tài)擴(kuò)展Metaspace內(nèi)存空間篙梢。程序加載超過10萬個(gè)類,而沒有出現(xiàn)OOM事件美旧。

JDK 1.8 @64-bit – Metaspace 受限測試

Java的Metaspace空間:128MB(-XX:MaxMetaspaceSize=128m)

可以從上面的JVisualVM的截圖看出:當(dāng)加載超過2萬個(gè)類之后渤滞,Metaspace被耗盡贬墩;與JDK1.7運(yùn)行時(shí)非常相似。我們也能通過程序和GC的輸出觀察耗盡的過程妄呕。另一個(gè)有趣的現(xiàn)象是陶舞,保留的原生內(nèi)存占用量是設(shè)定的最大大小兩倍之多。這可能表明绪励,如果可能的話吊说,可微調(diào)元空間容量大小策略,來避免本地內(nèi)存的浪費(fèi)优炬。

從Java程序的輸出中看到如下異常颁井。

[Loaded?ClassA?from?file:/D:/classes/]

total:21393

active:21393

unloaded:0

[GC?(Metadata?GC?Threshold)?64306K->57010K(111616K),0.0145502secs]

[Full?GC?(Metadata?GC?Threshold)?57010K->56810K(122368K),0.1068084secs]

java.lang.OutOfMemoryError:?Metaspace

在設(shè)置了MaxMetaspaceSize的情況下,該空間的內(nèi)存仍然會耗盡蠢护,進(jìn)而引發(fā)“java.lang.OutOfMemoryError: Metadata space”錯(cuò)誤雅宾。因?yàn)轭惣虞d器的泄漏仍然存在,而通常Java又不希望無限制地消耗本機(jī)內(nèi)存葵硕,因此設(shè)置一個(gè)類似于MaxPermSize的限制看起來也是合理的眉抬。

總結(jié)

之前不管是不是需要,JVM都會吃掉那塊空間……如果設(shè)置得太小懈凹,JVM會死掉蜀变;如果設(shè)置得太大,這塊內(nèi)存就被JVM浪費(fèi)了介评。理論上說库北,現(xiàn)在你完全可以不關(guān)注這個(gè),因?yàn)镴VM會在運(yùn)行時(shí)自動(dòng)調(diào)校為“合適的大小”们陆;

提高Full GC的性能寒瓦,在Full GC期間,Metadata到Metadata pointers之間不需要掃描了坪仇,別小看這幾納秒時(shí)間杂腰;

隱患就是如果程序存在內(nèi)存泄露,像OOMTest那樣椅文,不停的擴(kuò)展metaspace的空間喂很,會導(dǎo)致機(jī)器的內(nèi)存不足,所以還是要有必要的調(diào)試和監(jiān)控皆刺。

總結(jié)

Hotspot中的元數(shù)據(jù)現(xiàn)在存儲到了元空間里少辣。mmap中的內(nèi)存塊的生命周期與類加載器的一致。

類指針壓縮空間(Compressed class pointer space)目前仍然是固定大小的芹橡,但它的空間較大

可以進(jìn)行參數(shù)的調(diào)優(yōu)毒坛,不過這不是必需的。

未來可能會增加其它的優(yōu)化及新特性林说。比如煎殷, 應(yīng)用程序類數(shù)據(jù)共享;新生代GC優(yōu)化腿箩,G1回收器進(jìn)行類的回收豪直;減少元數(shù)據(jù)的大小,以及JVM內(nèi)部對象的內(nèi)存占用量珠移。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末弓乙,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子钧惧,更是在濱河造成了極大的恐慌暇韧,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件浓瞪,死亡現(xiàn)場離奇詭異懈玻,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)乾颁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門涂乌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人英岭,你說我怎么就攤上這事湾盒。” “怎么了诅妹?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵罚勾,是天一觀的道長。 經(jīng)常有香客問我吭狡,道長荧库,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任赵刑,我火速辦了婚禮分衫,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘般此。我一直安慰自己蚪战,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布铐懊。 她就那樣靜靜地躺著邀桑,像睡著了一般。 火紅的嫁衣襯著肌膚如雪科乎。 梳的紋絲不亂的頭發(fā)上壁畸,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼捏萍。 笑死太抓,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的令杈。 我是一名探鬼主播走敌,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼逗噩!你這毒婦竟也來了掉丽?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤异雁,失蹤者是張志新(化名)和其女友劉穎捶障,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體纲刀,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡项炼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了柑蛇。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片芥挣。...
    茶點(diǎn)故事閱讀 40,040評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖耻台,靈堂內(nèi)的尸體忽然破棺而出空免,到底是詐尸還是另有隱情,我是刑警寧澤盆耽,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布蹋砚,位于F島的核電站,受9級特大地震影響摄杂,放射性物質(zhì)發(fā)生泄漏坝咐。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一析恢、第九天 我趴在偏房一處隱蔽的房頂上張望墨坚。 院中可真熱鬧,春花似錦映挂、人聲如沸泽篮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽帽撑。三九已至,卻和暖如春鞍时,著一層夾襖步出監(jiān)牢的瞬間亏拉,已是汗流浹背扣蜻。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工及塘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留莽使,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓磷蛹,卻偏偏與公主長得像吮旅,于是被迫代替她去往敵國和親溪烤。 傳聞我的和親對象是個(gè)殘疾皇子味咳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評論 2 355

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