INSTRUMENTS调试工具的使用(九)

版本记录

版本号 时间
V1.0 2017.06.24

前言

我们在做app的时候,不是做完功能就结束了,很多时候是需要进行检查和优化的,而xcode自带了一个很好的检查工具,可以检测内存泄漏。还可以查看哪一个方法比较耗时。还可以检测离屏渲染等等,随后的几篇我们就说一下这个工具的使用。感兴趣的可以看这几篇。
1.INSTRUMENTS调试工具的使用(一)
2.INSTRUMENTS调试工具的使用(二)
3.INSTRUMENTS调试工具的使用(三)
4.INSTRUMENTS调试工具的使用(四)
5.INSTRUMENTS调试工具的使用(五)
6.INSTRUMENTS调试工具的使用(六)
7.INSTRUMENTS调试工具的使用(七)
8.INSTRUMENTS调试工具的使用(八)

这一篇就先说一下绘图、内存、系统、输入输出相关等

二十一、Graphics Instruments[绘图相关]

该部分的 instruments 工具收集和绘图相关的数据。

核心动画(Core Animation)

Core Animation instrument 工具测量一个运行在 iOS 设备上面的进程每秒的核 心动画帧的数量,以及屏幕外的帧计数。
  此外,Core Animation instrument 工具可以 供一个可视化的 示(hints)来帮 助你理解内容是如何被渲染到屏幕的。该 instrument 工具包含了许多可选的选项来 允许你选择特定类型的渲染 示(rendering hints)。 示工作在设备上的任何程序。 没有必要记录样本数据来激活提示。但你关闭 Instruments 文档或删除该 instrument 工具时, 示会被伴随关闭。如果有一个 OpenGL 的表层被显示,渲染 示不会影响 该表层。

该 instrument 工具包含以下的渲染提示:

  • 着色混合层(Color Blended Layers),放置一个红色(red)的覆盖层在使用混合绘画的图层上面。放置一个绿色(green)的覆盖层在不使用混合绘画的图层上面。
  • 着色复印的图像(Color Copied Images),放置一个蓝绿色(cyan)的覆盖层在核心动画复印的图像上面。
  • 立即着色(ColorImmediately),执行着色刷新操作之后,不需要等待10毫秒。
  • 着色未对齐的图像(Color Misaligned Images),放置一个洋红色(magenta)的覆盖层在源像素不对齐目标像素的图像上面。
  • 着色屏幕外渲染为黄色(Color Offscreen-Rendered Yellow),放置一个黄色的覆盖层在屏幕外渲染的内容上面。
  • 着色 OpenGL 快速路径为蓝色(Color OpenGL Fast Path Blue),放置一个蓝色的覆盖层在从合成器分离的内容之上。
  • 闪光更新的区域(Flash Updated Regions)屏幕闪光更新的区域为黄色。

跟踪面板可以显示每秒的帧数,扩展详细面板显示每个样本点的分析。

OpenGL驱动器(OpenGL Driver)

OpenGL Driver instrument 工具样本分析 OpenGL 的统计信息。该 instrument 工 具可以运行在单个进程或所有当前系统运行的进程上面。

该 instrument 工具捕获以下信息:

  • 交换缓冲区数(Buffer swap count)
  • 客户端 OpenGL 等待时间(Client GLWait time)
  • 每个样本的 2D 指令字节(Command 2D Bytes per sample)
  • 上下文 2D 的计数(Context 2D Count)
  • 上下文 OpenGL 计数(Context GLCount)
  • 上下文空闲缓冲区 2D 等待时间(Free Context Buffer 2D Wait time)
  • 图形地址映射表的字节大小(Gart size bytes)- Gart 为 Graphics Address Remapping Table
  • 表层计数(Surface count)
  • 纹理计数(Texture count)
  • 显存空闲字节(Vram free bytes)- Vram 为 Video Random Access Memory
  • 更多(and much more)

OpenGL ES驱动器(OpenGL ES Driver)

OpenGL ES Driver instrument 工具在 iOS 设备上查询 GPU 驱动器来给单独进程 进行 OpenGL 样本统计分析。该 instrument 工具帮你确定你已经使用了设备的 OpenGL 和 GPU 的效率。

GPU 的硬件由两部有效的组合:平铺器(Tiler)和渲染器(Renderer)。一个场景被 平铺并渲染。平铺器和渲染器组件通常工作在不同的场景。每个组件的利用率可能达 到 100%。

平铺器和渲染器利用率对于确定瓶颈很有帮助。渲染器利用率低下时意味着进程正等待被平铺,此时降低场景的复杂度可能对缓解利用率问题。平铺器和渲染器利用 率低下时暗示程序的其他地方出现了瓶颈。

该 instrument 工具捕获以下信息:

  • 上下文计数(ContextCount)全局OpenGL上下文的数量。需要注意的是可以有其他运行的进程(比如,SpringBoard)负责创建一个上下文。这一统计分析可以帮助你重点发现任何没有得到销毁的错误上下文。
  • 命令缓冲区分配的字节数(Command Buffer Allocated Bytes)被分配用于存储和提交命令缓冲区数据的字节数。该空间可以用来 交所有 OpenGL 命令和用户指定的顶点数据。
  • 命令缓冲区 交的字节数(Command Buffer Submitted Bytes)已经 交给驱动器的命令缓冲区字节数。该数量包括所有 OpenGL 命令和用户指定的顶点数据。 每次 交时,已 交字节数(Submitted Bytes)会从总的内存量里面递增。你 可能需要通过它除以 交次数(Submit Count)所得的值来获取每次 交的评价 使用值(该平均值总是稍微少于分配的字节数,因为分配的大小就是实际使用的 边界)。
  • 命令缓冲区 交的次数(Command Buffer Submit Count)驱动器处理的命令缓 冲区的次数。一个命令缓冲区也许包含多个渲染器和切换器。每个命令缓冲区被 传给 GPU 时,该值会随着递增(每个命令缓冲区可能包含零个或多个场景)。
  • 命令缓冲区渲染的次数(Command Buffer Render Count)GPU 渲染的 3D 帧的数 量。
  • 命令缓冲区切换次数(Command Buffer Transfer Count)驱动程序处理的交换 命令的显示次数。
  • 渲染利用率%(Renderer Utilization %)GPU 花在执行分片处理的时间比例。
  • 平铺器利用率%(Tiler Utilization %)GPU 花在顶点处理和平铺的时间比例。
  • 设备利用率%(DeviceUtilization%)GPU花在执行一些平铺和渲染工作的时间比例。
  • 平铺场景的字节数(Tiled Scene Bytes)用于平铺场景的字节数。值越大意味着场景越复杂。如果你的场景复杂到超出填充平铺场景的字节时,你可以使用分 割场景模式。但通常情况下你应该避免使用该模式。统计数据是由每个场景递加的。同时你需要使用字节数除以场景数。
  • 分割场景数(Split Scene Count)一个场景的部分进入分割场景模式的次数。但场景复杂度很高而且无法把整个场景填充进入一个平铺场景字节缓冲区的时 候,需要使用分割场景模式。分割的场景数和平铺场景字节数可以用来确定渲染 的路径,而且你需要降低该路径的复杂度。更多的时候你应该避免使用分割场景。
  • 资源字节数(Resource Bytes)用于纹理的字节数。
  • 资源计数(Resource Count)使用中的纹理的数量。
  • 每秒核心动画帧数(Core Animation Frames Per Second)核心动画每秒显示新的合成帧的数量。这些帧可能包含了 CAEAGLLayer 对象的 OpenGL ES 帧。 跟踪面板指示数据何时被收集的。

OpenGL ES分析器(OpenGL ES Analyzer)

应用程序每次调用 OpenGL ES 框架时,该 instrument 工具跟踪调用并记录时间、 时长、回溯跟踪和其他参数,并把信息更新到主机上。该 instrument 工具分析 OpenGL 命令流来计算有用的性能分析数据并驱动专业系统,然后反过来提供修正建议和性能建议。

比如,该 instrument 工具可能会告诉你它检测到没有使用顶点缓冲区对象的顶点数据数组。顶点数组是保存在主内存的客户端数据。如果把这些数据以顶点缓冲区 对象上传到 GPU 的话将会更加高效。尽管它的实现有点复杂,但性能提高是显著的。

该 instrument 工具 供以下视图:

  • 帧统计(Frame statistics):对应图形的时间刻度,它会以表格形式呈现图形中渲染的数据。
  • 分析结果(Analysis findings):专业系统的建议,和扩展详细视图的栈跟踪。使用不同的颜色来标示问题的严重性。你可以扩展子层来查看每个建议的特定事件,然后更深层的扩展来查看由建议产生的 OpenGL ES 命令的序列。
  • 跟踪功能(Functiontrace)OpenGL命令的全部列表,和扩展详细视图的参数和回溯跟踪。
  • API统计(APIstatistics)列出OpenGL调用唯一总时间和每次调用的平均时间。
  • 调用树(Call tree) 供所有用户调用 OpenGL ES 或 EAGL 函数的导航,利用instrument 工具的数据挖掘工具。

但你双击分析结果或跟踪功能的回溯跟踪符合时,将会显示相关的源码。 覆盖部分是用来绕过在图形管道的阶段。这可让你隔离问题并找到你的代码中的瓶颈。


二十二、 Input/Output Instruments[输入输出相关]

以下的 instrument 工具收集和 I/O 操作相关的数据。

读/写(Reads/Wirtes)

Reads/Writes instrument 工具记录文件的读取和写入操作。该 instrument 工具 可以运行在单个进程或系统当前运行的所有进程之上。该 instrument 工具的实现使 用了 DTrace,并可以导入 DTrace 脚本。它收集关于每个读取和写入函数的相关信息, 包括 read、write、pread 和 pwrite。

该 instrument 工具捕获以下信息:

  • 函数的名称
  • 函数的调用者(包括可执行文件的名称和栈跟踪信息)
  • 可执行文件操作的文件的路径
  • 被修改文件的 述
  • 读取或写入的字节树

跟踪面板可以被设置来显示以下的数据:

  • 栈深度(Stack depth)
  • 线程 ID(Thread ID)
  • 文件描述符(File descriptor)
  • 字节数(Bytes)

二十三、Master Tracks Instruments[界面操作跟踪相关]

主跟踪轨迹(Master Tracks)部分包含了用户界面的记录器,它可以让你记录并回放程序中用户的一系列动作。

用户界面(User Interface)

User Interface instrument 工具可以加载一个程序或附加到一个进程之上,并 记录你和界面之间的交互。你可以多次回放这些记录,并运行任何其他你选择的 instruments 工具进行这样的操作。你可以使用该instrument 工具来创建作为你质量保证计划的一部分的用户界面的可重复测试,并捕获偶然发生的错误。


二十四、Memory Instruments[内存相关]

该部分的 instruments 工具跟踪内存使用情况。

共享内存(Shared Memory)

Shared Memory instrument 工具记录共享内存的打开和取消链接。该 instrument 工具可以运行在单个进程或系统当前正在运行的所有进程之上。该 instrument 工具 的实现使用了 DTrace 并可以导入 DTrace 脚本。它收集关于每个共享内存的访问信息, 包括 shm_open 和 shm_unlink。

该 instrument 工具捕获以下信息:

  • 函数的名称
  • 函数的调用者(包括可执行文件的名称和栈跟踪信息)
  • 共享内存区域的名称
  • 用来打开共享内存区域的标记(查看shm_open主页)
  • 模式标记,指示该共享区域的访问权限(查看chmod主页)

跟踪面板可以被设置来显示以下的数据:

  • 栈深度(Stack depth)
  • 线程 ID(Thread ID)
  • 标志(Flags)
  • mode_t

分配内存(Allocations)

Allocations instrument 工具跟踪应用的内存分配情况。该 instrument 工具要求你加载一个进程,以便它能收集进程开始之后的数据。

该 instrument 工具捕获以下信息:

  • 类别(Category)通常是一个 Core Foundation 对象、Objective-C 类、或原始内存块(block)。
  • 净分配字节数(Net Bytes)当前已经分配内存但是仍然没有被释放的字节的总数。
  • 净分配数(#Net)当前已经分配内存但仍然没有被释放的对象或内存块的数量。
  • 总分配字节数(Overall Bytes)所有已经分配内存,而且包括已经被释放了的字节的总数。
  • 总分配数(#Overall)所有当前已经分配内存,包括已经被释放了的对象或内存块的总数。
  • 净余或全部内存分配(#Allocations)当前和全部分配数的直方图。直方条通常为蓝色。当对象总数和最大值之间的比例或最大值和当前分配数的比例少于1/3 时,直方条会被修改为黄色。当比例等于 1/10 或更少时,直方条变为红色。
    尽管显示的比例不一定是坏事(通常它们在应用程序长期运行期间是正常),Instruments 应用通常给它们标示不同的颜色来指出分配模式以便进行进一步的研 究。如果你发现类别(categories)的颜色为红色或黄色,你可能需要尽量消除应用 程序给定类型的非必要的临时内存分配。类似的,你可能只是简单的尽量消除高水位 标记的对象的数量。

当你鼠标移动到详细面板上面的类别名称上时,会在类别名称的旁边显示一个更多信息的按钮。单击该按钮会显示关于该类别上的对象的详细信息,包含以下属性:

  • 块(block)地址。
  • 函数调用或造成该分配事件的类。比如,你可以看到该类里面的那个方法对对象进行了引用。
  • 对象的创建时间。
  • 负责创建对象的库。

对于任一这些事件,你可以打开扩展详细面板来查看每个对象内存分配的栈跟 踪,包括分配的类型和事件发生的时间。
  对于特定对象(或内存块)的实例,你可以单击该对象地址列的更多信息按钮来 查看对象相关的内存分配事件。对于每个内存分配事件,该 instrument 工具显示以下信息:

  • 对象(它的类型)的类别
  • 事件类型
  • 每个事件的时间戳
  • 块地址
  • 块的大小
  • 负责分配块的库
  • 引发分配事件的函数

为了进一步的过滤详细面板的信息,你可以配置 Allocation Lifespan options(内存分配存活期选项)。这些选项可以让你过滤基于以下标准的分配事件:

  • 所有创建的对象(All Objects Created) - 显示所有对象,无论它们是否已经被释放掉了。
  • 已创建的&仍然有效的(Created & Still Living) - 仅显示当你停止记录时仍然存在内存的对象。

Allocations instrument 工具的检查器可以让你配置 instrument 工具跟踪信息 的方法。你可以从该检查器设置一下选项:

  • 记录引用数。使用该选项来跟踪每个对象的引用计数。
  • 停止时丢弃未被记录的数据。使用该选项来丢弃任何已经被收集了的当还没被Allocations instrument 工具处理的数据。

关于 Allocations instrument 工具的更多额外信息,参阅“使用 Allocations Instrument 工具分析数据(Analyzing Data with the Allocations Instrument)”。

内存泄露(Leaks)

Leaks instrument 工具检查进程堆泄露的内存。你可以使用该 instrument 工具 配合 Allocations instrument 工具来获取内存地址的历史记录。该 instrument 工具 要求你加载一个进程以便它可以从进程启动时收集数据。

该 instrument 工具捕获以下信息:

  • 内存泄露的数量(The number of leaks)
  • 每个泄露内存块的大小(The size of each leak)
  • 泄露内存块的地址(Address of the leaked block)
  • 泄露对象的类型(Type of the leadked object)

详细面板的每个视图模式以轻微不同的函数显示泄露的数据。在列表模式下,该 instrument 工具显示每个泄露的百分比,而每个内存泄露有助于发现内存泄露的总 数。在大纲模式下,数据被重组以便你可以查看给定的符号有多少内存泄露。对于任 何模式的条目,在扩展详细面板显示内存泄露引发的深入栈跟踪信息。
  关于 Leaks instrument 工具的更多额外信息,参阅“查找内存泄露(Looking for Memory)”。


二十五、System Instruments[系统相关]

该部分的 instruments 工具收集系统活动和资源的数据。

时间分析器(Time Profiler)

  Time Profiler instrument 工具在规定的间隔内停止一个 Mac OS X 的程序并记 录该程序内部线程的栈跟踪信息。你可以使用这些信息来确定花费在你程序上面的执 行时间并 升你的代码来减少运行时间。不像很多 instruments 工具,Time Profiler 工具不需要使用 DTrace 探针来实现功能。Time Profiler 工具运行在单个进程或所 有进程之上。

在采样期间,该 instrument 工具捕获以下信息:

  • 采样开始的时间
  • 采样的时长
  • 栈跟踪信息(包括库和调用者信息)
  • 采样期间遇到的最大栈深度
  • 采样期间遇到的最频繁的函数(热点帧)

  Time Profiler 工具让你可以以不同的方式来查看这些信息。在列表模式下,你 可以查看按照时间顺序采集的样本,它显示你代码执行的顺序。在大纲模式下,Time Profiler 提供了你程序调用栈的树形视图并显示了调用栈里对应调用函数的样本数量。

  为了显示一个函数的详细调用栈,你可以在大纲模式下扩展对应的项目或选择一 个函数并打开扩展详细面板。在大纲模式下,你可以通过单击 Option 键和条目的扩 展三角形来扩大给定条目的整个调用栈。

  跟踪面板默认显示每个样本时间点的栈深度。该视图对于确定你代码执行的情况 很有帮助。因为它不像两个不同的执行路径结果产生相同的栈深度,当你查看图形的 重复结构时,它可能是相同的代码被重复的执行。

   Time Profiler instrument 工具和 Sampler instrument 工具有点类似,但是它 们之间也有很多的不同:

  • TimeProfil以诈骗(Shark)的方式从内核空间收集回溯跟踪数据。而Sampler工具从用户空间收集数据。因此,Time Profiler 在收集数据方面比 Sampler 工 具更高效。
    注意:如果目标进程被优化来忽略帧指针,那么 Time Profiler(以 Shark 方式)可能 产生不准确的回溯跟踪数据。
  • Time Profiler 可以收集一个或多个进程的数据。Sampler 工具只能采集单一进 程。
  • Time Profiler 可以采集所有线程状态或只在当前运行的线程。Sampler 工具通 常采样所有线程状态。通常情况下,你可能只对正在运行的线程感兴趣。当你的 应用被挂起时,你需要检查所有线程的状态。

旋转监控器(Spin Monitor)

  Spin Monitor instrument 工具自动采样系统上无响应的应用程序。当一个应用 程序 3 秒或更长内没有从窗口服务器检索事件时,它将会变为无响应的应用程序。在 这段时间内没有响应的应用程序实际上可能会做一些有益的工作,也可能是被挂起。 你可以该 instrument 工具生成的样本信息来修改你的代码以便保证你的程序可以一 直保持及时处理事件。该 instrument 工具可以运行在单个进程或系统当前运行的所 有进程之上。

在采样期间,该 instrument 工具捕获以下信息:

  • 采样开始时间
  • 采样的时长
  • 栈跟踪信息(包括库和调用者信息)
  • 采样期间遇到的最大栈深度
  • 采样期间遇到的最频繁的函数(热帧)

取样(Sampler)

  Sampler instrument 工具在指定的时间间隔内停止一个应用程序并记录应用程 序每个线程的栈跟踪信息。你可以使用这些信息来确定花费你应用程序执行时间的地 方并 高你的代码来减少运行时间。不像许多 instruments 工具,Sampler instrument 工具不要求使用 DTrace 探针来实现功能。该 instrument 工具运行在单个进程之上。
Sampler instrument 工具记录每个样本的以下数据类型:

  • 被执行的函数
  • 应用程序每个线程的栈跟踪信息
  • 样本被采集的时间

  Sampler instrument 工具可以让你以不同的方式查看这些信息。在列表模式下, 你可以按照样本被采集的顺序来查看它们,它显示了你代码执行的顺序。在大纲模式 下,Sampler instrument 工具 供了你应用程序调用栈的树型视图,并显示了里面 每个调用函数执行时的样本的数量。
  在研究的一个正在运行程序的性能时,你应该比较函数的影响和函数的执行成 本。如果你的程序花费很长的时间来执行一个低影响的函数,该 instrument 工具可 以标记出该请情况。然后你可以使用样本数据来找出为何你的程序会花费这些时间和 谁调用这些函数,通过这样你可以修复你的代码让它减少被调用的频率。

  跟踪面板默认显示每个样本时间点的栈深度。该视图可以帮助识别你代码当前正在做什么。因为两个不同的执行路径不太可能产生相同的栈深度,所以当你看到图形 有重复的结构时,有可能是同一代码被重复执行了。如果该段代码需要消耗很长时间 来执行,那它就是很好的优化目标。

  关于 Sampler instrument 工具的额外信息,参阅“使用 Sampler Instrument 工 具分析数据部分(Analyzing Data with the Sampler Instrument)”。

进程(Process)

  Process instrument 工具记录由另外进程派生的进程。该 Instrument 工具可以 运行在单个进程或系统所有当前运行的进程之上。该 instrument 工具的实现使用了 DTrace,并可以导入 DTrace 脚本。

该 instrument 工具捕获以下信息:

  • 执行一个进程(execve)
  • 进程退出(exit)

Process instrument 工具返回这些函数每次调用的信息,包括:

  • 函数名称(execve或exit)
  • 函数调用者(包括可执行文件名称,路径,和栈跟踪信息)
  • 进程ID
  • 进程退出状态

跟踪面板可以被设置来显示以下任何数据:

  • 栈深度(Stack depth)
  • 线程 ID(Thread ID)
  • 进程 ID(Process ID)
  • 退出状态(Exit status)

网络活动监控器(Network Activity Monitor)

  Network Activity Monitor instrument 工具记录电脑网络传输信息。该 instrument 工具可以运行在单个进程或系统当前所有运行的进程之上。跟踪面板可以被设置来默认显示以下网络相关的数据,但你也可以配置它来显示 其他类型的数据。
默认情况下,它显示以下信息:

  • 每秒发送的字节数量
  • 每秒收接收字节的数量
  • 每秒发送包的数量
  • 每秒接收包的数量

内存监控器(Memory Monitor)

  Memory Monitor instrument 工具记录进程使用的实际内存和虚拟内存的数量。 该 instrument 工具可以运行在单个进程或系统所有当前运行的进程之上。跟踪面板可以被设置来默认显示以下内存相关的数据,但你也可以配置它来显示 其他类型的数据。
默认情况下,它显示以下的信息:

  • 虚拟内存页面交换进入的数量(virtual memory page ins)
  • 虚拟内存页面交换出去的数量(virtual memory page outs)
  • 正在使用的虚拟内存空间的总数量
  • 空闲物理内存的总数量
  • 已用物理内存的总数量

硬盘监控器(Disk Monitor)

  Disk Monitor instrument 工具记录硬盘的读取和写入操作。该 instrument 工具 可以运行在单个进程或系统所有当前运行的进程之上。跟踪面板可以被设置来默认显示以下和硬盘相关的数据,但你也可以配置它来显 示其他类型的数据。
默认情况下,它显示以下信息:

  • 每秒写入硬盘的字节数量
  • 每秒从硬盘读取的字节数量
  • 每秒处理的写操作的数量
  • 每秒处理的读操作的数量

CPU监控器(CPU Monitor)

  CPU Monitor instrument 工具记录系统的负载。该 instrument 工具可以运行在 单个进程或系统所有当前运行的进程之上。跟踪面板可以被设置来默认显示以下负载值,但你也可以配置它来显示其他类型 的数据。
默认情况下,它显示以下信息:

  • 系统产生的负载的数量
  • 用户产生的负载的数量
  • 系统总负载

活动监控器(Activity Monitor)

  Activity Monitor instrument 记录由虚拟内存大小测量的系统负载。该 instrument 工具可以运行在单个进程或系统所有当前运行的进程之上。跟踪面板可以被设置来默认显示以下的负载值,你也可以配置它来显示其他类型 的数据。
默认情况下,它显示以下信息:

  • 正在使用的虚拟内存控件的总量
  • 系统产生的负载数量
  • 用户产生的负载数量
  • 系统总负载

后记

未完,待续~~~

太阳
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容