这篇文章讲述网络报文从网卡 NIC (network interface controller)接收,再到操作系统网络协议栈处理,最后到用户程序接收报文处理报文的简化过程,希望能对TCP协议进行一个整体、概括性的总结。

阅读全文 »

几乎所有的现代编程语言都使用动态内存分配,即允许进程在运行时分配或释放无法在编译期确定大小的对象,这些对象的存活时间有可能超出创建者的生存周期。动态分配的对象存在于堆(heap)中而不是栈(stack)或者静态区(statically)中。在内存的管理方式上,有两种方式:1)显示内存释放,由开发人员显示的创建或释放对象;2)自动动态内存管理,由编程语言的运行时系统(虚拟机)负责内存的回收。自动动态内存管理可以显著地降低开发成本,提供程序的健壮性。我们这篇文章主要便是讲述内存管理中常用垃圾回收算法,并结合 java 来分析内部的实现。

垃圾回收的目的是回收程序不再使用的对象所占用的空间,任何具备自动内存管理系统的语言都要有三个功能:

  1. 为新对象分配空间;
  2. 确定存活对象;
  3. 回收死亡对象所占用的空间。

内存分配与回收是相关性比较强的两个功能,内存管理系统都要具备这两个功能;在实现中,使用指针的可达性来近似对象的存活:只有当堆中存在一条从根出发的指针链能最终到达某个对象时,才能认定该对象存活,更进一步,如果不存在这一条指针链,则认为对象死亡,其空间可以得到回收。回收死亡对象包括两种方式:1)直接释放该对象,有可能会与前后的空闲对象进行合并;2)将存活对象进行移动或整理,减少内存碎片的问题。

阅读全文 »

1. 概述

处于优化的目的,在不同的编译器及不同体系架构的cpu 中,会将指令重排,即程序中排在后面的指令有可能比排在前面的指令先执行。同时由于cpu 中存在读写缓冲区,会将指令相关的运行时数据暂存在这些缓冲区中,也会导致指令重排的问题。目前的cpu 都是多核的体系架构,同一个语言编写的程序在不同硬件体系中,在多线程执行环境下,多次执行的结果可能不一致。在Java 中,怎么解决这个问题?为了屏蔽不同硬件架构的差异,给程序员提供一致的运行结果,Java 提出了 JMM(内存模型)的概念。

阅读全文 »

在数据库技术中,事务将应用程序的多个读、写操作捆绑在一起成为一个逻辑操作单元。即事务中的所有读写是一个执行的整体,整个事务要么成功(提交)、要么失败(中止或回滚)。如果失败,应用程序可以安全地重试。这样,由于不需要担心部分失败的情况(无论出于何种原因),应用层的错误处理就变得简单得多。

阅读全文 »

概括来讲,存储引擎分为两大类:针对事务处理(OLTP)优化的结构,以及针对分析型(OLAP)的优化结构。它们典型的访问模式存在很大的差异:

  • OLTP系统通常面向用户,这意味着它们可能收到大量的请求。为了处理负载,应用程序通常在每个用户查询中只涉及小量的记录。应用程序基于某种键来请求记录,而存储引擎使用索引来查找所请求的数据。磁盘寻道时间往往是瓶颈。

  • 由于不直接面对最终用户,数据仓库和类似的分析系统相对并不太广为人知,它们主要由业务分析师使用。处理的查询请求数目远低于OLTP系统,但每个查询通常要求非常苛刻,需要在短时间内扫描百万条记录。磁盘带宽(不是寻道时间)通常是瓶颈,而面向列的存储对于这种工作负载成为日益流行的解决方案。 在OLTP方面,有两个主要流派的存储引擎:

  • 日志结构流派:它只允许追加方式更新文件和删除过时的文件,但不会修改已写入的文件。BitCask、SSTable、LST-Tree、LevelDB、Cassandra、HBase、Lucence等属于此类;

  • 原地更新流派:将磁盘视为可以覆盖的一组固定大小的页。B-Tree是这个哲学的最典型代表,它已用于所有主要的关系数据库,以及大量的非关系数据库。

日志结构的存储引擎是一个相对较新的方案。其关键思想是系统地将磁盘上随机访问写入转为顺序写入,由于硬盘驱动器和SSD的性能特性,可以实现更高的写入吞吐量。下面将针对这两种存储引擎进行分析。

阅读全文 »
0%