【搞定Jvm面試】 JDK監(jiān)控和故障處理工具揭秘

本文已經(jīng)收錄自筆者開(kāi)源的 JavaGuide: https://github.com/Snailclimb (【Java學(xué)習(xí)+面試指南】 一份涵蓋大部分Java程序員所需要掌握的核心知識(shí))如果覺(jué)得不錯(cuò)的還,不妨去點(diǎn)個(gè)Star兔沃,鼓勵(lì)一下!

JDK 監(jiān)控和故障處理工具總結(jié)

JDK 命令行工具

這些命令在 JDK 安裝目錄下的 bin 目錄下:

  • jps (JVM Process Status): 類似 UNIX 的 ps 命令折欠。用戶查看所有 Java 進(jìn)程的啟動(dòng)類、傳入?yún)?shù)和 Java 虛擬機(jī)參數(shù)等信息焰情;
  • jstat( JVM Statistics Monitoring Tool): 用于收集 HotSpot 虛擬機(jī)各方面的運(yùn)行數(shù)據(jù);
  • jinfo (Configuration Info for Java) : Configuration Info forJava,顯示虛擬機(jī)配置信息;
  • jmap (Memory Map for Java) :生成堆轉(zhuǎn)儲(chǔ)快照;
  • jhat (JVM Heap Dump Browser ) : 用于分析 heapdump 文件渐夸,它會(huì)建立一個(gè) HTTP/HTML 服務(wù)器撕彤,讓用戶可以在瀏覽器上查看分析結(jié)果;
  • jstack (Stack Trace for Java):生成虛擬機(jī)當(dāng)前時(shí)刻的線程快照,線程快照就是當(dāng)前虛擬機(jī)內(nèi)每一條線程正在執(zhí)行的方法堆棧的集合榆苞。

jps:查看所有 Java 進(jìn)程

jps(JVM Process Status) 命令類似 UNIX 的 ps 命令稳衬。

jps:顯示虛擬機(jī)執(zhí)行主類名稱以及這些進(jìn)程的本地虛擬機(jī)唯一 ID(Local Virtual Machine Identifier,LVMID)。jps -q :只輸出進(jìn)程的本地虛擬機(jī)唯一 ID坐漏。

C:\Users\SnailClimb>jps
7360 NettyClient2
17396
7972 Launcher
16504 Jps
17340 NettyServer

jps -l:輸出主類的全名薄疚,如果進(jìn)程執(zhí)行的是 Jar 包,輸出 Jar 路徑赊琳。

C:\Users\SnailClimb>jps -l
7360 firstNettyDemo.NettyClient2
17396
7972 org.jetbrains.jps.cmdline.Launcher
16492 sun.tools.jps.Jps
17340 firstNettyDemo.NettyServer

jps -v:輸出虛擬機(jī)進(jìn)程啟動(dòng)時(shí) JVM 參數(shù)街夭。

jps -m:輸出傳遞給 Java 進(jìn)程 main() 函數(shù)的參數(shù)。

jstat: 監(jiān)視虛擬機(jī)各種運(yùn)行狀態(tài)信息

jstat(JVM Statistics Monitoring Tool) 使用于監(jiān)視虛擬機(jī)各種運(yùn)行狀態(tài)信息的命令行工具躏筏。 它可以顯示本地或者遠(yuǎn)程(需要遠(yuǎn)程主機(jī)提供 RMI 支持)虛擬機(jī)進(jìn)程中的類信息板丽、內(nèi)存、垃圾收集趁尼、JIT 編譯等運(yùn)行數(shù)據(jù)埃碱,在沒(méi)有 GUI,只提供了純文本控制臺(tái)環(huán)境的服務(wù)器上酥泞,它將是運(yùn)行期間定位虛擬機(jī)性能問(wèn)題的首選工具乃正。

jstat 命令使用格式:

jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

比如 jstat -gc -h3 31736 1000 10表示分析進(jìn)程 id 為 31736 的 gc 情況,每隔 1000ms 打印一次記錄婶博,打印 10 次停止,每 3 行后打印指標(biāo)頭部荧飞。

常見(jiàn)的 option 如下:

  • jstat -class vmid :顯示 ClassLoader 的相關(guān)信息凡人;
  • jstat -compiler vmid :顯示 JIT 編譯的相關(guān)信息;
  • jstat -gc vmid :顯示與 GC 相關(guān)的堆信息叹阔;
  • jstat -gccapacity vmid :顯示各個(gè)代的容量及使用情況挠轴;
  • jstat -gcnew vmid :顯示新生代信息;
  • jstat -gcnewcapcacity vmid :顯示新生代大小與使用情況耳幢;
  • jstat -gcold vmid :顯示老年代和永久代的信息岸晦;
  • jstat -gcoldcapacity vmid :顯示老年代的大信菲 ;
  • jstat -gcpermcapacity vmid :顯示永久代大衅羯稀邢隧;
  • jstat -gcutil vmid :顯示垃圾收集信息;

另外冈在,加上 -t參數(shù)可以在輸出信息上加一個(gè) Timestamp 列倒慧,顯示程序的運(yùn)行時(shí)間。

jinfo: 實(shí)時(shí)地查看和調(diào)整虛擬機(jī)各項(xiàng)參數(shù)

jinfo vmid :輸出當(dāng)前 jvm 進(jìn)程的全部參數(shù)和系統(tǒng)屬性 (第一部分是系統(tǒng)的屬性包券,第二部分是 JVM 的參數(shù))纫谅。

jinfo -flag name vmid :輸出對(duì)應(yīng)名稱的參數(shù)的具體值。比如輸出 MaxHeapSize溅固、查看當(dāng)前 jvm 進(jìn)程是否開(kāi)啟打印 GC 日志 ( -XX:PrintGCDetails :詳細(xì) GC 日志模式付秕,這兩個(gè)都是默認(rèn)關(guān)閉的)。

C:\Users\SnailClimb>jinfo  -flag MaxHeapSize 17340
-XX:MaxHeapSize=2124414976
C:\Users\SnailClimb>jinfo  -flag PrintGC 17340
-XX:-PrintGC

使用 jinfo 可以在不重啟虛擬機(jī)的情況下侍郭,可以動(dòng)態(tài)的修改 jvm 的參數(shù)询吴。尤其在線上的環(huán)境特別有用,請(qǐng)看下面的例子:

jinfo -flag [+|-]name vmid 開(kāi)啟或者關(guān)閉對(duì)應(yīng)名稱的參數(shù)。

C:\Users\SnailClimb>jinfo  -flag  PrintGC 17340
-XX:-PrintGC

C:\Users\SnailClimb>jinfo  -flag  +PrintGC 17340

C:\Users\SnailClimb>jinfo  -flag  PrintGC 17340
-XX:+PrintGC

jmap:生成堆轉(zhuǎn)儲(chǔ)快照

jmap(Memory Map for Java)命令用于生成堆轉(zhuǎn)儲(chǔ)快照励幼。 如果不使用 jmap 命令汰寓,要想獲取 Java 堆轉(zhuǎn)儲(chǔ),可以使用 “-XX:+HeapDumpOnOutOfMemoryError” 參數(shù)苹粟,可以讓虛擬機(jī)在 OOM 異常出現(xiàn)之后自動(dòng)生成 dump 文件有滑,Linux 命令下可以通過(guò) kill -3 發(fā)送進(jìn)程退出信號(hào)也能拿到 dump 文件。

jmap 的作用并不僅僅是為了獲取 dump 文件嵌削,它還可以查詢 finalizer 執(zhí)行隊(duì)列毛好、Java 堆和永久代的詳細(xì)信息,如空間使用率苛秕、當(dāng)前使用的是哪種收集器等肌访。和jinfo一樣,jmap有不少功能在 Windows 平臺(tái)下也是受限制的艇劫。

示例:將指定應(yīng)用程序的堆快照輸出到桌面吼驶。后面,可以通過(guò) jhat店煞、Visual VM 等工具分析該堆文件蟹演。

C:\Users\SnailClimb>jmap -dump:format=b,file=C:\Users\SnailClimb\Desktop\heap.hprof 17340
Dumping heap to C:\Users\SnailClimb\Desktop\heap.hprof ...
Heap dump file created

jhat: 分析 heapdump 文件

jhat 用于分析 heapdump 文件,它會(huì)建立一個(gè) HTTP/HTML 服務(wù)器顷蟀,讓用戶可以在瀏覽器上查看分析結(jié)果酒请。

C:\Users\SnailClimb>jhat C:\Users\SnailClimb\Desktop\heap.hprof
Reading from C:\Users\SnailClimb\Desktop\heap.hprof...
Dump file created Sat May 04 12:30:31 CST 2019
Snapshot read, resolving...
Resolving 131419 objects...
Chasing references, expect 26 dots..........................
Eliminating duplicate references..........................
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.

訪問(wèn) http://localhost:7000/

jstack :生成虛擬機(jī)當(dāng)前時(shí)刻的線程快照

jstack(Stack Trace for Java)命令用于生成虛擬機(jī)當(dāng)前時(shí)刻的線程快照。線程快照就是當(dāng)前虛擬機(jī)內(nèi)每一條線程正在執(zhí)行的方法堆棧的集合.

生成線程快照的目的主要是定位線程長(zhǎng)時(shí)間出現(xiàn)停頓的原因鸣个,如線程間死鎖羞反、死循環(huán)布朦、請(qǐng)求外部資源導(dǎo)致的長(zhǎng)時(shí)間等待等都是導(dǎo)致線程長(zhǎng)時(shí)間停頓的原因。線程出現(xiàn)停頓的時(shí)候通過(guò)jstack來(lái)查看各個(gè)線程的調(diào)用堆棧昼窗,就可以知道沒(méi)有響應(yīng)的線程到底在后臺(tái)做些什么事情是趴,或者在等待些什么資源。

下面是一個(gè)線程死鎖的代碼膏秫。我們下面會(huì)通過(guò) jstack 命令進(jìn)行死鎖檢查右遭,輸出死鎖信息,找到發(fā)生死鎖的線程缤削。

public class DeadLockDemo {
    private static Object resource1 = new Object();//資源 1
    private static Object resource2 = new Object();//資源 2

    public static void main(String[] args) {
        new Thread(() -> {
            synchronized (resource1) {
                System.out.println(Thread.currentThread() + "get resource1");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread() + "waiting get resource2");
                synchronized (resource2) {
                    System.out.println(Thread.currentThread() + "get resource2");
                }
            }
        }, "線程 1").start();

        new Thread(() -> {
            synchronized (resource2) {
                System.out.println(Thread.currentThread() + "get resource2");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread() + "waiting get resource1");
                synchronized (resource1) {
                    System.out.println(Thread.currentThread() + "get resource1");
                }
            }
        }, "線程 2").start();
    }
}

Output

Thread[線程 1,5,main]get resource1
Thread[線程 2,5,main]get resource2
Thread[線程 1,5,main]waiting get resource2
Thread[線程 2,5,main]waiting get resource1

線程 A 通過(guò) synchronized (resource1) 獲得 resource1 的監(jiān)視器鎖窘哈,然后通過(guò)Thread.sleep(1000);讓線程 A 休眠 1s 為的是讓線程 B 得到執(zhí)行然后獲取到 resource2 的監(jiān)視器鎖。線程 A 和線程 B 休眠結(jié)束了都開(kāi)始企圖請(qǐng)求獲取對(duì)方的資源亭敢,然后這兩個(gè)線程就會(huì)陷入互相等待的狀態(tài)滚婉,這也就產(chǎn)生了死鎖。

通過(guò) jstack 命令分析:

C:\Users\SnailClimb>jps
13792 KotlinCompileDaemon
7360 NettyClient2
17396
7972 Launcher
8932 Launcher
9256 DeadLockDemo
10764 Jps
17340 NettyServer

C:\Users\SnailClimb>jstack 9256

輸出的部分內(nèi)容如下:

Found one Java-level deadlock:
=============================
"線程 2":
  waiting to lock monitor 0x000000000333e668 (object 0x00000000d5efe1c0, a java.lang.Object),
  which is held by "線程 1"
"線程 1":
  waiting to lock monitor 0x000000000333be88 (object 0x00000000d5efe1d0, a java.lang.Object),
  which is held by "線程 2"

Java stack information for the threads listed above:
===================================================
"線程 2":
        at DeadLockDemo.lambda$main$1(DeadLockDemo.java:31)
        - waiting to lock <0x00000000d5efe1c0> (a java.lang.Object)
        - locked <0x00000000d5efe1d0> (a java.lang.Object)
        at DeadLockDemo$$Lambda$2/1078694789.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:748)
"線程 1":
        at DeadLockDemo.lambda$main$0(DeadLockDemo.java:16)
        - waiting to lock <0x00000000d5efe1d0> (a java.lang.Object)
        - locked <0x00000000d5efe1c0> (a java.lang.Object)
        at DeadLockDemo$$Lambda$1/1324119927.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:748)

Found 1 deadlock.

可以看到 jstack 命令已經(jīng)幫我們找到發(fā)生死鎖的線程的具體信息帅刀。

JDK 可視化分析工具

JConsole:Java 監(jiān)視與管理控制臺(tái)

JConsole 是基于 JMX 的可視化監(jiān)視让腹、管理工具】勰纾可以很方便的監(jiān)視本地及遠(yuǎn)程服務(wù)器的 java 進(jìn)程的內(nèi)存使用情況骇窍。你可以在控制臺(tái)輸出console命令啟動(dòng)或者在 JDK 目錄下的 bin 目錄找到jconsole.exe然后雙擊啟動(dòng)。

連接 Jconsole

連接 Jconsole

如果需要使用 JConsole 連接遠(yuǎn)程進(jìn)程锥余,可以在遠(yuǎn)程 Java 程序啟動(dòng)時(shí)加上下面這些參數(shù):

-Djava.rmi.server.hostname=外網(wǎng)訪問(wèn) ip 地址 
-Dcom.sun.management.jmxremote.port=60001   //監(jiān)控的端口號(hào)
-Dcom.sun.management.jmxremote.authenticate=false   //關(guān)閉認(rèn)證
-Dcom.sun.management.jmxremote.ssl=false

在使用 JConsole 連接時(shí)腹纳,遠(yuǎn)程進(jìn)程地址如下:

外網(wǎng)訪問(wèn) ip 地址:60001 

查看 Java 程序概況

查看 Java 程序概況

內(nèi)存監(jiān)控

JConsole 可以顯示當(dāng)前內(nèi)存的詳細(xì)信息。不僅包括堆內(nèi)存/非堆內(nèi)存的整體信息驱犹,還可以細(xì)化到 eden 區(qū)嘲恍、survivor 區(qū)等的使用情況,如下圖所示雄驹。

點(diǎn)擊右邊的“執(zhí)行 GC(G)”按鈕可以強(qiáng)制應(yīng)用程序執(zhí)行一個(gè) Full GC佃牛。

  • 新生代 GC(Minor GC):指發(fā)生新生代的的垃圾收集動(dòng)作,Minor GC 非常頻繁医舆,回收速度一般也比較快俘侠。
  • 老年代 GC(Major GC/Full GC):指發(fā)生在老年代的 GC,出現(xiàn)了 Major GC 經(jīng)常會(huì)伴隨至少一次的 Minor GC(并非絕對(duì))蔬将,Major GC 的速度一般會(huì)比 Minor GC 的慢 10 倍以上爷速。
內(nèi)存監(jiān)控

線程監(jiān)控

類似我們前面講的 jstack 命令,不過(guò)這個(gè)是可視化的娃胆。

最下面有一個(gè)"檢測(cè)死鎖 (D)"按鈕,點(diǎn)擊這個(gè)按鈕可以自動(dòng)為你找到發(fā)生死鎖的線程以及它們的詳細(xì)信息 等曼。

線程監(jiān)控

Visual VM:多合一故障處理工具

VisualVM 提供在 Java 虛擬機(jī) (Java Virutal Machine, JVM) 上運(yùn)行的 Java 應(yīng)用程序的詳細(xì)信息里烦。在 VisualVM 的圖形用戶界面中凿蒜,您可以方便、快捷地查看多個(gè) Java 應(yīng)用程序的相關(guān)信息胁黑。Visual VM 官網(wǎng):https://visualvm.github.io/ 废封。Visual VM 中文文檔:https://visualvm.github.io/documentation.html

下面這段話摘自《深入理解 Java 虛擬機(jī)》丧蘸。

VisualVM(All-in-One Java Troubleshooting Tool)是到目前為止隨 JDK 發(fā)布的功能最強(qiáng)大的運(yùn)行監(jiān)視和故障處理程序漂洋,官方在 VisualVM 的軟件說(shuō)明中寫上了“All-in-One”的描述字樣,預(yù)示著他除了運(yùn)行監(jiān)視力喷、故障處理外刽漂,還提供了很多其他方面的功能,如性能分析(Profiling)弟孟。VisualVM 的性能分析功能甚至比起 JProfiler贝咙、YourKit 等專業(yè)且收費(fèi)的 Profiling 工具都不會(huì)遜色多少,而且 VisualVM 還有一個(gè)很大的優(yōu)點(diǎn):不需要被監(jiān)視的程序基于特殊 Agent 運(yùn)行拂募,因此他對(duì)應(yīng)用程序的實(shí)際性能的影響很小庭猩,使得他可以直接應(yīng)用在生產(chǎn)環(huán)境中。這個(gè)優(yōu)點(diǎn)是 JProfiler陈症、YourKit 等工具無(wú)法與之媲美的蔼水。

VisualVM 基于 NetBeans 平臺(tái)開(kāi)發(fā),因此他一開(kāi)始就具備了插件擴(kuò)展功能的特性录肯,通過(guò)插件擴(kuò)展支持趴腋,VisualVM 可以做到:

  • 顯示虛擬機(jī)進(jìn)程以及進(jìn)程的配置、環(huán)境信息(jps嘁信、jinfo)于样。
  • 監(jiān)視應(yīng)用程序的 CPU、GC潘靖、堆穿剖、方法區(qū)以及線程的信息(jstat、jstack)卦溢。
  • dump 以及分析堆轉(zhuǎn)儲(chǔ)快照(jmap糊余、jhat)。
  • 方法級(jí)的程序運(yùn)行性能分析单寂,找到被調(diào)用最多贬芥、運(yùn)行時(shí)間最長(zhǎng)的方法。
  • 離線程序快照:收集程序的運(yùn)行時(shí)配置宣决、線程 dump蘸劈、內(nèi)存 dump 等信息建立一個(gè)快照,可以將快照發(fā)送開(kāi)發(fā)者處進(jìn)行 Bug 反饋尊沸。
  • 其他 plugins 的無(wú)限的可能性......

這里就不具體介紹 VisualVM 的使用威沫,如果想了解的話可以看:

公眾號(hào)

如果大家想要實(shí)時(shí)關(guān)注我更新的文章以及分享的干貨的話贤惯,可以關(guān)注我的公眾號(hào)。

《Java面試突擊》: 由本文檔衍生的專為面試而生的《Java面試突擊》V2.0 PDF 版本公眾號(hào)后臺(tái)回復(fù) "Java面試突擊" 即可免費(fèi)領(lǐng)劝袈印孵构!

Java工程師必備學(xué)習(xí)資源: 一些Java工程師常用學(xué)習(xí)資源公眾號(hào)后臺(tái)回復(fù)關(guān)鍵字 “1” 即可免費(fèi)無(wú)套路獲取。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末烟很,一起剝皮案震驚了整個(gè)濱河市颈墅,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌雾袱,老刑警劉巖恤筛,帶你破解...
    沈念sama閱讀 212,542評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異谜酒,居然都是意外死亡叹俏,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門僻族,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)粘驰,“玉大人,你說(shuō)我怎么就攤上這事述么◎蚴” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 158,021評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵度秘,是天一觀的道長(zhǎng)顶伞。 經(jīng)常有香客問(wèn)我,道長(zhǎng)剑梳,這世上最難降的妖魔是什么唆貌? 我笑而不...
    開(kāi)封第一講書人閱讀 56,682評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮垢乙,結(jié)果婚禮上锨咙,老公的妹妹穿的比我還像新娘。我一直安慰自己追逮,他們只是感情好酪刀,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,792評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著钮孵,像睡著了一般骂倘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上巴席,一...
    開(kāi)封第一講書人閱讀 49,985評(píng)論 1 291
  • 那天历涝,我揣著相機(jī)與錄音,去河邊找鬼。 笑死荧库,一個(gè)胖子當(dāng)著我的面吹牛诱担,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播电爹,決...
    沈念sama閱讀 39,107評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼料睛!你這毒婦竟也來(lái)了丐箩?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 37,845評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤恤煞,失蹤者是張志新(化名)和其女友劉穎屎勘,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體居扒,經(jīng)...
    沈念sama閱讀 44,299評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡概漱,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,612評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了喜喂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瓤摧。...
    茶點(diǎn)故事閱讀 38,747評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖玉吁,靈堂內(nèi)的尸體忽然破棺而出照弥,到底是詐尸還是另有隱情,我是刑警寧澤进副,帶...
    沈念sama閱讀 34,441評(píng)論 4 333
  • 正文 年R本政府宣布这揣,位于F島的核電站,受9級(jí)特大地震影響影斑,放射性物質(zhì)發(fā)生泄漏给赞。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,072評(píng)論 3 317
  • 文/蒙蒙 一矫户、第九天 我趴在偏房一處隱蔽的房頂上張望片迅。 院中可真熱鬧,春花似錦吏垮、人聲如沸障涯。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,828評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)唯蝶。三九已至,卻和暖如春遗嗽,著一層夾襖步出監(jiān)牢的瞬間粘我,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,069評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留征字,地道東北人都弹。 一個(gè)月前我還...
    沈念sama閱讀 46,545評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像匙姜,于是被迫代替她去往敵國(guó)和親畅厢。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,658評(píng)論 2 350

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

  • 今天窩在娘家一天氮昧。 一張大床四個(gè)人睡一起的感覺(jué)非常好框杜,兜七點(diǎn)半鬧鐘響了就起來(lái)早讀,新一背1復(fù)1袖肥,古詩(shī)背1復(fù)2咪辱。學(xué)校...
    江小米米閱讀 79評(píng)論 0 0
  • 依然是開(kāi)出花來(lái)系列 這次的小元素是雨鞋那種膠鞋 這次有參考圖片 很喜歡這張圖片的顏色和花朵~ 雨鞋的刻畫比較簡(jiǎn)單 ...
    植植植植與閱讀 522評(píng)論 4 8
  • 轉(zhuǎn)載出處:http://www.reibang.com/p/e385ce41ca5b 概念 Java類中不僅可以定...
    今晚打肉山閱讀 214評(píng)論 0 1
  • 我最喜歡的小動(dòng)物就是小狗了,奶奶家有一只小狗椎组,名字叫小花油狂,每次見(jiàn)到我很遠(yuǎn)它就會(huì)搖晃著小尾巴迎接我,我拍拍它的頭寸癌,它...
    王紫萱萱閱讀 190評(píng)論 0 0
  • AlphaGo與李世石之間的人機(jī)大戰(zhàn)落下帷幕专筷, AlphaGo以4:1大獲全勝。有個(gè)有意思的現(xiàn)象蒸苇,一方面仁堪,我身邊很...
    宋旸閱讀 195評(píng)論 0 0