instanceSize詳解

一脓魏、instanceSize方法的底層實(shí)現(xiàn)

首先需要知道罢猪,對象的內(nèi)存空間里存放的是對象的屬性师抄,所以計(jì)算內(nèi)存大小即為計(jì)算所有屬性所占的內(nèi)存大小谐区,先看下objc源碼的底層實(shí)現(xiàn):

size_t instanceSize(size_t extraBytes) const {

    //方式一:編譯器快速計(jì)算內(nèi)存大泻伞(16字節(jié)對齊)
    if (fastpath(cache.hasFastInstanceSize(extraBytes))) {
        return cache.fastInstanceSize(extraBytes);
    }

    //方式二:計(jì)算類中所有屬性和方法的內(nèi)存占用 + 額外的字節(jié)數(shù)0(8字節(jié)對齊)
    size_t size = alignedInstanceSize() + extraBytes;
    //CF requires all objects be at least 16 bytes.
    //最少申請16字節(jié)的內(nèi)存大小
    if (size < 16) size = 16;
    return size;
}

上面兩個方式的區(qū)別,在于將對象所有屬性所占的內(nèi)存大小采取不同的對齊方式宋列,方式一是16字節(jié)對齊昭抒,方式二是8字節(jié)對齊。

注意炼杖,在不同版本的objc源碼中灭返,instanceSize方法的底層實(shí)現(xiàn)可能是不一樣的,本文參照的是最新的objc-781源碼坤邪,里面會有這兩種計(jì)算方式熙含,但是實(shí)際運(yùn)行,其實(shí)是以方式一來計(jì)算的罩扇,16字節(jié)內(nèi)存對齊婆芦。而在老版本的objc源碼中怕磨,比如objc-750源碼喂饥,里面只有方式二的計(jì)算方式消约,采取的是8字節(jié)對齊。

//objc-750源碼中的instanceSize方法
size_t instanceSize(size_t extraBytes) {

    size_t size = alignedInstanceSize() + extraBytes;
    // CF requires all objects be at least 16 bytes.
    if (size < 16) size = 16;
    return size;
}

雖然這個方法的底層實(shí)現(xiàn)不會頻繁更新员帮,但大家以后在分析時或粮,最好是參照最新的objc源碼進(jìn)行分析。話不多說捞高,接下來分析這兩種方式具體是怎么計(jì)算的氯材。

1.1 十六字節(jié)對齊 - fastInstanceSize

從源碼中可知,是在fastInstanceSize方法里完成內(nèi)存計(jì)算的:

size_t fastInstanceSize(size_t extra) const
{
    ASSERT(hasFastInstanceSize(extra));

    if (__builtin_constant_p(extra) && extra == 0) {
        return _flags & FAST_CACHE_ALLOC_MASK16;
    } else {
        size_t size = _flags & FAST_CACHE_ALLOC_MASK;
        // remove the FAST_CACHE_ALLOC_DELTA16 that was added
        // by setFastInstanceSize
        return align16(size + extra - FAST_CACHE_ALLOC_DELTA16);
    }
}

編譯器快速計(jì)算出需要的size后硝岗,最后會執(zhí)行align16方法氢哮,即『16字節(jié)對齊』。

static inline size_t align16(size_t x) {
    return (x + size_t(15)) & ~size_t(15);
}

系統(tǒng)在計(jì)算出內(nèi)存size后型檀,會先加15冗尤,再與個非15,這樣就實(shí)現(xiàn)了16字節(jié)對齊胀溺。接下來通過兩組二進(jìn)制運(yùn)算來直觀地看看字節(jié)對齊后的結(jié)果:

//已知: 15的二進(jìn)制為: 0000 1111   
//      ~15的二進(jìn)制為:1111 0000

//假設(shè)計(jì)算出當(dāng)前類需要的內(nèi)存大小為12字節(jié)裂七,則16字節(jié)對齊的計(jì)算過程如下:
0000 1100    // 12字節(jié)
0000 1111    // +15
0001 1011    // = 27
1111 0000    // ~15
0001 0000    // 27 & (~15)  = 16

//假設(shè)計(jì)算出當(dāng)前類需要的內(nèi)存大小為24字節(jié),則16字節(jié)對齊的計(jì)算過程如下:
0001 1000    // 24字節(jié)
0000 1111    // +15
0010 0111    // = 39
1111 0000    // ~15
0010 0000    // 39 & (~15)  = 32

從上面兩組二進(jìn)制運(yùn)算得知仓坞,12字節(jié)背零、24字節(jié)的內(nèi)存經(jīng)由16字節(jié)對齊后,實(shí)際申請內(nèi)存大小分別為16字節(jié)无埃、32字節(jié)徙瓶。因此,不管對象屬性實(shí)際需要多大的內(nèi)存空間嫉称,在新版本中侦镇,系統(tǒng)都會以16字節(jié)的倍數(shù)來申請內(nèi)存空間,并且最少16字節(jié)澎埠,這就是『16字節(jié)對齊』虽缕。

1.2 八字節(jié)對齊 - alignedInstanceSize
size_t size = alignedInstanceSize() + extraBytes;
// CF requires all objects be at least 16 bytes.
if (size < 16) size = 16;
return size;

在實(shí)例化對象時,經(jīng)由斷點(diǎn)調(diào)試可知蒲稳,extraBytes為0氮趋,所以內(nèi)存大小依賴于alignedInstanceSize方法計(jì)算:

uint32_t alignedInstanceSize() {

    //step1:通過unalignedInstanceSize方法獲取到需要的內(nèi)存大小
    //step2:通過word_align方法對內(nèi)存大小進(jìn)行8字節(jié)運(yùn)算
    return word_align(unalignedInstanceSize());
}

可以看到,class_getInstanceSize方法最終實(shí)現(xiàn)就兩步江耀,先獲取到對象屬性所占的內(nèi)存大小剩胁,再將內(nèi)存大小進(jìn)行8字節(jié)對齊運(yùn)算。

  • unalignedInstanceSize
uint32_t unalignedInstanceSize() const {
    ASSERT(isRealized());
    return data()->ro()->instanceSize;
}

這一步獲取到的是對象的屬性所占的內(nèi)存大小祥国,ro是個很重要的知識點(diǎn)昵观,會在后續(xù)介紹類和對象的結(jié)構(gòu)時作詳細(xì)講解晾腔,本篇文章就不作過多拓展了。

  • word_align
#define WORD_MASK 7UL
static inline uint32_t word_align(uint32_t x) {
    return (x + WORD_MASK) & ~WORD_MASK;
}

WORD_MASK的值為7啊犬,這里其實(shí)是對內(nèi)存大小作8字節(jié)對齊運(yùn)算灼擂。對齊計(jì)算和上文的16進(jìn)制對齊一樣,大家可以自己進(jìn)行二進(jìn)制演算觉至,這里就不再推演了剔应。在完成8字節(jié)對齊運(yùn)算后,還會再判斷size的大小语御,如果小于16峻贮,就申請16字節(jié)的內(nèi)存。 也就是說应闯,不管對象的屬性實(shí)際需要多大的內(nèi)存纤控,在老版本中,系統(tǒng)都會以8字節(jié)的倍數(shù)來申請內(nèi)存空間碉纺,并且最少16字節(jié)船万。

二、對內(nèi)存進(jìn)行字節(jié)對齊的原因

理解了內(nèi)存對齊邏輯后惜辑,可能會有疑問唬涧,為什么要對內(nèi)存進(jìn)行字節(jié)對齊呢?為什么不按對象屬性實(shí)際占用的內(nèi)存大小來分配內(nèi)存呢盛撑?經(jīng)由字節(jié)對齊后碎节,分配的空間要比實(shí)際需要的多,這樣會不會造成內(nèi)存浪費(fèi)抵卫?

在解答這些疑問前狮荔,我們需要先清楚,對象里可能會有多種數(shù)據(jù)類型的屬性介粘,這些屬性占用內(nèi)存大小是不一樣的殖氏,如果直接按照實(shí)際需要內(nèi)存進(jìn)行分配,則cpu在讀取內(nèi)存數(shù)據(jù)時需要先知道每個數(shù)據(jù)占用多大內(nèi)存姻采,這樣才能保證讀取的數(shù)據(jù)是完整的雅采,讀取效率較低。

下面這個表格是各種類型數(shù)據(jù)分別在32位和64位系統(tǒng)中占用內(nèi)存的大小慨亲,單位:字節(jié)婚瓜。(注:本文都是基于64位系統(tǒng)分析的)

C OC 32位 64位
bool BooL(64位) 1 1
signed char (_ _signed char)int8_t、BOOL(32位) 1 1
unsigned char Boolean 1 1
short int16_t 2 2
unsigned short unichar 2 2
int刑棵、int32_t NSInteger(32位)巴刻、boolean_ t(32位) 4 4
unsigned int boolean_ t(64位)、NSUInteger(32位) 4 4
long NSInteger(64位) 4 8
unsigned long NSUlnteger(64位) 4 8
long long int64_t 8 8
float CGFloat(32位) 4 4
double CGFloat(64位) 8 8

從表格里清晰的看到蛉签,屬性最多占用8字節(jié)內(nèi)存胡陪。而對象里最常見的屬性是指針類型沥寥,指針類型的數(shù)據(jù)在內(nèi)存里也是占用8字節(jié)的大小。這樣柠座,以8字節(jié)的倍數(shù)來開辟內(nèi)存空間邑雅,CPU再以8字節(jié)為一段進(jìn)行讀取,既能保證每個數(shù)據(jù)讀取的完整性愚隧,又能提高讀取效率蒂阱,這就是最初系統(tǒng)8字節(jié)對齊的原因锻全。

舉個例子狂塘,創(chuàng)建一個Person對象,對象里有多種數(shù)據(jù)類型的屬性鳄厌,來看看字節(jié)對齊對分配內(nèi)存的影響荞胡。(注:這里只是看下字節(jié)對齊的影響,就先不考慮isa指針了)

@interface Person : NSObject

@property (nonatomic, strong) NSString *name;  //8
@property (nonatomic, strong) NSString *sex;   //8
@property (nonatomic, assign) int age;         //4
@property (nonatomic, assign) long height;     //8
@property (nonatomic) char c1;    //1
@property (nonatomic) char c2;    //1

@end

如果不作字節(jié)對齊了嚎,那么系統(tǒng)分配內(nèi)存會是下面的情況:

image

系統(tǒng)如果以屬性實(shí)際占用內(nèi)存大小來分配泪漂,雖然有效利用了內(nèi)存空間,但是在讀取數(shù)據(jù)時歪泳,CPU就需要預(yù)先知道每個屬性占用的內(nèi)存大小萝勤,并按對應(yīng)字節(jié)長度讀取讀取內(nèi)存,否則讀取的數(shù)據(jù)就不完整呐伞。
比如敌卓,在上圖中,若讀取age數(shù)據(jù)伶氢,如果此時CPU不按照4字節(jié)長度來讀取趟径,要么沒讀取到完整的age數(shù)據(jù),要么會越界讀到height的數(shù)據(jù)癣防。
因此蜗巧,系統(tǒng)如果以屬性實(shí)際占用內(nèi)存大小來分配,CPU讀取內(nèi)存數(shù)據(jù)時既不安全蕾盯,效率也低幕屹。

所以系統(tǒng)會對內(nèi)存進(jìn)行字節(jié)對齊,內(nèi)存分配情況大致如下(注:不是一定按照這個順序的):

image

若進(jìn)行字節(jié)對齊级遭,在分配內(nèi)存時望拖,會進(jìn)行屬性重排,將age装畅、c1靠娱、c2(總共6字節(jié))這三個屬性存在一個8字節(jié)段中,在讀取數(shù)據(jù)時掠兄,CPU也是按照8字節(jié)為一段來讀取像云,這樣既能保證讀取數(shù)據(jù)的完整性锌雀,又能提高讀取效率。雖說會多開辟幾字節(jié)的內(nèi)存空間迅诬,但是保證了讀取安全腋逆,提高了讀取效率,完全是值得的侈贷。而且鑒于現(xiàn)在設(shè)備內(nèi)存越來越大惩歉,這種『以空間換時間』來提高效率的方式,會越來越常見俏蛮。

三撑蚌、計(jì)算對象申請的內(nèi)存空間大小

內(nèi)存空間里保存的是對象的屬性,所以計(jì)算內(nèi)存空間大小即是統(tǒng)計(jì)對象所有屬性所占的內(nèi)存大小搏屑。需要注意的是争涌,對象都是繼承自NSObject的,NSObject里有個isa成員屬性辣恋,是指針類型亮垫,需要占用8字節(jié)內(nèi)存。

//NSObjct的結(jié)構(gòu)
@interface NSObject <NSObject> {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-interface-ivars"
    Class isa  OBJC_ISA_AVAILABILITY;
#pragma clang diagnostic pop
}

isa的具體用途后面會講解伟骨,本文不再拓展饮潦。在接下來的內(nèi)存計(jì)算中,都需要加上其占用的8字節(jié)內(nèi)存携狭。

按照前面的思路继蜡,計(jì)算對象實(shí)例化時申請的內(nèi)存空間大小,即先統(tǒng)計(jì)所有屬性所占的內(nèi)存大小暑中,然后再進(jìn)行16字節(jié)對齊就可得到壹瘟。那怎么印證這個計(jì)算規(guī)則呢?最直觀的方法就是獲取并打印對象的內(nèi)存size鳄逾,之前有看過其他文章稻轨,很多都是通過class_getInstanceSize方法來獲取的,先來看下這個方法的實(shí)現(xiàn)邏輯:

size_t class_getInstanceSize(Class cls){

    if (!cls) return 0;
    return cls->alignedInstanceSize();
}

可以看到雕凹,class_getInstanceSize方法里面調(diào)用的是alignedInstanceSize方法殴俱,就回到了上文1.2里面的八字節(jié)對齊處理了,所以如果是老版本枚抵,就可以正常使用线欲,對于新版本的16字節(jié)對齊就不適用了。在新版本里可以改寫這個方法的對齊運(yùn)算汽摹,然后再使用李丰,比如這樣:

//將8字節(jié)對齊改成16字節(jié)對齊
size_t class_getInstanceSize(Class cls)
{
    if (!cls) return 0;
//    return cls->alignedInstanceSize();
    return cls->instanceSize(0);
}

但為了更直觀的區(qū)分8字節(jié)和16字節(jié)的對齊結(jié)果,這里我選擇在class_createInstanceFromZone方法里打印需要申請的內(nèi)存大小逼泣。

  • 先在objc-runtime-new.h文件里添加一個老版本8字節(jié)對齊的方法趴泌。
//這也是objc-750版本的instanceSize方法
size_t oldInstanceSize(size_t extraBytes) const {

    size_t size = alignedInstanceSize() + extraBytes;
    // CF requires all objects be at least 16 bytes.
    if (size < 16) size = 16;
    return size;
}

  • 然后在class_createInstanceFromZone方法里再獲取一個8字節(jié)對齊的結(jié)果舟舒,并將兩種對齊方式的內(nèi)存大小打印出來。
//這是原本的16字節(jié)對齊計(jì)算
size_t size;
size = cls->instanceSize(extraBytes);
if (outAllocatedSize) *outAllocatedSize = size;

//這里再獲取一個8字節(jié)對齊結(jié)果
size_t size8;
size8 = cls->oldInstanceSize(extraBytes);

//打印兩個結(jié)果
printf("size16 = %lu \nsize8 = %lu\n", size, size8);

  • 最后實(shí)例化Person對象嗜憔,打印結(jié)果秃励。為了對比更加直觀,也打印出通過class_getInstanceSize方法獲取到的內(nèi)存大小吉捶。

準(zhǔn)備工作完成夺鲜,那接下來分析在各種情況下創(chuàng)建Person對象需要申請的內(nèi)存空間大小。

3.1 不含任何自定義屬性的Person對象
//不含自定義屬性的Person對象
@interface Person : NSObject
@end

//創(chuàng)建Person對象呐舔,打印內(nèi)存大小
Person *person = [[Person alloc] init];
NSLog(@"class_getInstanceSize = %lu", class_getInstanceSize([Person class]));

//打印結(jié)果
size16 = 16                 //16字節(jié)對齊的結(jié)果
size8 = 16                  //8字節(jié)對齊的結(jié)果
class_getInstanceSize = 8   //獲取的8字節(jié)對齊的內(nèi)存

person對象里只有一個isa屬性币励,占8字節(jié),那屬性總共占用8字節(jié)的內(nèi)存大凶淘纭:

  • size16 = 16:經(jīng)由16字節(jié)對齊后榄审,結(jié)果為16字節(jié)。
  • size8 = 16:經(jīng)由8字節(jié)對齊后杆麸,結(jié)果為8字節(jié)。但oldInstanceSize方法最后對內(nèi)存大小進(jìn)行了判斷浪感,如果小于16昔头,就返回16。
  • class_getInstanceSize = 8:這個方法只作了8字節(jié)對齊影兽,所以返回為8揭斧。
3.2 自定義指針類型屬性的Person對象
//聲明兩個指針類型的屬性
@interface Person : NSObject

@property (nonatomic, strong) NSString *name;  //8
@property (nonatomic, strong) NSString *sex;   //8

@end

//創(chuàng)建Person對象,打印內(nèi)存大小
Person *person = [[Person alloc] init];
NSLog(@"class_getInstanceSize = %lu", class_getInstanceSize([Person class]));

//打印結(jié)果
size16 = 32                  //16字節(jié)對齊的結(jié)果
size8 = 24                   //8字節(jié)對齊的結(jié)果
class_getInstanceSize = 24   //獲取的8字節(jié)對齊的內(nèi)存

person對象里有三個指針類型的數(shù)據(jù)(isa峻堰,name讹开,sex),屬性總共占用24字節(jié)的內(nèi)存大芯杳:

  • size16 = 32:經(jīng)由16字節(jié)對齊后旦万,結(jié)果為32字節(jié)。
  • size8 = 24:經(jīng)由8字節(jié)對齊后镶蹋,結(jié)果為24字節(jié)成艘。
  • class_getInstanceSize = 24:這個方法只作了8字節(jié)對齊,所以返回為24贺归。
3.3 自定義多種數(shù)據(jù)類型屬性的Person對象
//Person類里自定義了多種類型的屬性
@interface Person : NSObject

@property (nonatomic, strong) NSString *name;  //8
@property (nonatomic, strong) NSString *sex;   //8
@property (nonatomic, assign) int age;         //4
@property (nonatomic, assign) long height;     //8
@property (nonatomic) char c1;                 //1
@property (nonatomic) char c2;                 //1

@end

//創(chuàng)建Person對象淆两,打印內(nèi)存大小
Person *person = [[Person alloc] init];
NSLog(@"class_getInstanceSize = %lu", class_getInstanceSize([Person class]));

//打印結(jié)果
size16 = 48                  //16字節(jié)對齊的結(jié)果
size8 = 40                   //8字節(jié)對齊的結(jié)果
class_getInstanceSize = 40   //獲取的8字節(jié)對齊的內(nèi)存

person對象里的屬性總共占用38字節(jié)的內(nèi)存大小:

  • size16 = 48:經(jīng)由16字節(jié)對齊后拂酣,結(jié)果為48字節(jié)秋冰。
  • size8 = 40:經(jīng)由8字節(jié)對齊后,結(jié)果為40字節(jié)婶熬。
  • class_getInstanceSize = 40:這個方法只作了8字節(jié)對齊剑勾,所以返回為40光坝。
3.4 對象里包含結(jié)構(gòu)體成員屬性

在Person對象里添加結(jié)構(gòu)體成員,再看下打印結(jié)果甥材。

//聲明一個結(jié)構(gòu)體struct1盯另,根據(jù)前面的分析可知,內(nèi)存為24洲赵。
struct Struct1 {
    double a;   // 8 
    char b;     // 1
    int c;      // 4
    short d;    // 2
};

//在person最后面添加一個struct1的類
@interface Person : NSObject

@property (nonatomic, strong) NSString *name;  //8
@property (nonatomic, assign) int age;         //4
@property (nonatomic, assign) long height;     //8
@property (nonatomic) char c1;    //1
@property (nonatomic) struct Struct1 str;    //24

@end

//創(chuàng)建Person對象鸳惯,打印內(nèi)存大小
Person *person = [[Person alloc] init];
NSLog(@"class_getInstanceSize = %lu", class_getInstanceSize([Person class]));

//打印結(jié)果
size16 = 64                  //16字節(jié)對齊的結(jié)果
size8 = 56                   //8字節(jié)對齊的結(jié)果
class_getInstanceSize = 56   //獲取的8字節(jié)對齊的內(nèi)存

person對象其他屬性占用了29個字節(jié),在對象內(nèi)存里存放在位置0-28 叠萍。結(jié)構(gòu)體str成員芝发,本應(yīng)該在位置29處開始存放,但根據(jù)結(jié)構(gòu)體內(nèi)存對齊規(guī)則苛谷,當(dāng)結(jié)構(gòu)體作為成員時辅鲸,則結(jié)構(gòu)體成員要從其內(nèi)部最?元素所占內(nèi)存??的整數(shù)倍地址開始存儲,結(jié)構(gòu)體str里最大成員占用8字節(jié)內(nèi)存腹殿,所以str需要從8的整數(shù)倍開始存儲独悴,即從位置32開始存放,存放位置為32-55锣尉,所以最后person對象需要56字節(jié)內(nèi)存:

  • size16 = 64:經(jīng)由16字節(jié)對齊后刻炒,結(jié)果為64字節(jié)。
  • size8 = 56:經(jīng)由8字節(jié)對齊后自沧,結(jié)果為56字節(jié)坟奥。
  • class_getInstanceSize = 56:這個方法只作了8字節(jié)對齊,所以返回為56拇厢。

通過分析上述示例的打印結(jié)果爱谁,均可印證前面說的內(nèi)存大小的計(jì)算規(guī)則:先統(tǒng)計(jì)所有屬性所占的內(nèi)存大小,然后再進(jìn)行16字節(jié)對齊孝偎。簡單數(shù)據(jù)類型的屬性所占內(nèi)存比較容易統(tǒng)計(jì)访敌,但對于比較復(fù)雜的數(shù)據(jù)結(jié)構(gòu),比如說結(jié)構(gòu)體(struct)邪媳,它的內(nèi)存計(jì)算就需要遵循『內(nèi)存對齊規(guī)則』捐顷。

四、總結(jié)

  • 對象的內(nèi)存大小依賴其包含的屬性雨效,所以在實(shí)例化對象時迅涮,系統(tǒng)會先統(tǒng)計(jì)對象所有屬性所占的內(nèi)存大小,再經(jīng)由16字節(jié)對齊(老版本是8字節(jié)對齊)徽龟,計(jì)算出需要申請的內(nèi)存空間大小叮姑,所以對象的內(nèi)存大小只會是16的整數(shù)倍,并且最少申請16字節(jié)大小的內(nèi)存。

  • 對內(nèi)存大小作16字節(jié)對齊或8字節(jié)對齊传透,主要是為了保證cpu讀取內(nèi)存數(shù)據(jù)的安全耘沼,以及提高讀取效率。

  • 若數(shù)據(jù)類型為結(jié)構(gòu)體(struct)朱盐,在計(jì)算內(nèi)存大小時需要遵循結(jié)構(gòu)體內(nèi)存對齊原則群嗤,詳細(xì)介紹可參考下方推薦閱讀里的『數(shù)據(jù)結(jié)構(gòu) -- 結(jié)構(gòu)體Struct』一文。

五兵琳、幫助

在打印內(nèi)存大小時狂秘,可能會需要下面這三個方法:

  • sizeof:是一個運(yùn)算符,用來計(jì)算傳進(jìn)來的數(shù)據(jù)類型占用多大的內(nèi)存躯肌,在編譯時即可完成運(yùn)算者春。
  • class_getInstanceSize:獲取對象實(shí)例化時需要申請的內(nèi)存大小,采取的是8字節(jié)對齊方式清女,調(diào)用時需要先引用#import <objc/runtime.h>钱烟。
  • malloc_size:獲取對象實(shí)例化時系統(tǒng)實(shí)際開辟的內(nèi)存大小,采取的是16字節(jié)對齊方式嫡丙,調(diào)用時需要先引用#import <malloc/malloc.h>拴袭。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市迄沫,隨后出現(xiàn)的幾起案子稻扬,更是在濱河造成了極大的恐慌,老刑警劉巖羊瘩,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異盼砍,居然都是意外死亡尘吗,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進(jìn)店門浇坐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來睬捶,“玉大人,你說我怎么就攤上這事近刘∏苊常” “怎么了?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵觉渴,是天一觀的道長介劫。 經(jīng)常有香客問我,道長案淋,這世上最難降的妖魔是什么座韵? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上誉碴,老公的妹妹穿的比我還像新娘宦棺。我一直安慰自己,他們只是感情好黔帕,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布代咸。 她就那樣靜靜地躺著,像睡著了一般成黄。 火紅的嫁衣襯著肌膚如雪呐芥。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天慨默,我揣著相機(jī)與錄音贩耐,去河邊找鬼。 笑死厦取,一個胖子當(dāng)著我的面吹牛潮太,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播虾攻,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼铡买,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了霎箍?” 一聲冷哼從身側(cè)響起奇钞,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎漂坏,沒想到半個月后景埃,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡顶别,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年谷徙,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片驯绎。...
    茶點(diǎn)故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡完慧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出剩失,到底是詐尸還是另有隱情屈尼,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布拴孤,位于F島的核電站脾歧,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏乞巧。R本人自食惡果不足惜涨椒,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蚕冬,春花似錦免猾、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至旁蔼,卻和暖如春锨苏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背棺聊。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工伞租, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人限佩。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓葵诈,卻偏偏與公主長得像,于是被迫代替她去往敵國和親祟同。 傳聞我的和親對象是個殘疾皇子作喘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評論 2 348

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