zoukankan      html  css  js  c++  java
  • 2017-2018-1 20155329 《信息安全系统设计基础》第11周学习总结

    2017-2018-1 20155329 《信息安全系统设计基础》第11周学习总结

    教材学习内容总结

    虚拟存储器
    • 虚拟存储器是硬件异常、硬件地址翻译、主存、磁盘文件和内核软件的完美交互,它为每个进程提供了一个大的、一致的和私有的地址空间。
    • 虚拟存储器提供了三个重要的能力:
    1. 它将主存看成是一个存储在磁盘上的地址空间的高速缓存,在主存中只保存活动区域,并根据需要在磁盘和主存之间来回传送数据,通过这种方式,它高效地使用了主存。
    2. 它为每个进程提供了一致的地址空间,从而简化了存储器管理。
    3. 它保护了每个进程的地址空间不被其他进程破坏。
    如何理解虚拟存储器
    • 虚拟存储器是中心的。
    • 虚拟存储器是强大的。
    • 虚拟存储器是危险的。

    地址翻译

    • 地址翻译符号小结:

    存储器映射

    • Linux (以及其他一些形式的 Unix) 通过将一个虚拟存储器区域与一个磁盘上的对象 (object) 关联起来,以初始化这个虚拟存储器区域的内容,这个过程称为存储器映射 (memory mapping)。
    1. Unix 文件系统中的普通文件:一个区域可以映射到一个普通磁盘文件的连续部分。文件区 (sectÎon) 被分成页大小的片,每一片包含一个虚拟页面的初始内容。因为按需进行页面调度,所以这些虚拟页面没有实际交换进入物理存储器,直到 CPU 第一 次引用到页面(即发射一个虚拟地址,落在地址空间这个页面的范围之内)。如果区域比文件区要大,那么就用零来填充这个区域的余下部分。
    2. 匿名文件:一个区域也可以映射到一个匿名文件,匿名文件是由内核创建的,包含的全是二进制零。 CPU 第一次引用这样一个区域内的虚拟页面时,内核就在物理存储器中找到一个 合适的牺牲页面,如果该页面被修改过,就将这个页面换出来,用二进制零覆盖牺牲页面并更新页表,将这个页面标记为是驻留在存储器中的。注意在磁盘和存储器之间并没有实际的数据传送。因为这个原因,映射到匿名文件的区域中的页面有时也叫做请求二进制零的页 (demand zeropage)。
      一旦一个虚拟页面被初始化了,它就在一个由内核维护的专门的交换文件 (swap file) 之间换来换去。交换文件也叫做交换空间 (swap space) 或者交换区域 (swap area)。在任何时刻,交换空间都限制着当前运行着的进程能够 分配的虚拟页面的总数。

    动态存储器分配

    • 当运行时需要额外虚拟存储器时,用动态存储器分配器 (dynamic memory allocator) 更方便,也有更好的可移植性。
    • 动态存储器分配器维护着一个进程的虚拟存储器区域,称为堆 (heap)
    • 分配器将堆视为一组不同大小的块 (block) 的 集合来维护。每个块就是一个连续的虚拟存储器片 (chunk),要么是已分配的,要么是空闲的。己分配的 块显式地保留为供应用程序使用。空闲块可用来分配。空闲块保持空闲,直到它显式地被应用所分配。一个已分配的块保持已分配状态,直到它被释放,这种释放要么是应用程序显式执行的,要么是存储器分配器自身隐式执行的。
    • 分配器有两种基本风格。两种风格都要求应用显式地分配块。它们的不同之处在于由哪个实体来负责释放己分配的块。
    • 显式分配器 (explicit allocator),要求应用显式地 释放任何已分配的块。
    • 隐式分配器 (implicit allocator),另一方面,要求分配器检测一个已分配块何时不再被程序 所使用,那么就释放这个块。隐式分配器也叫做垃圾收集器 (garbage collector),而自动释放未使用的己分配的块的过程叫做垃圾收集 (garbage collection)。
    为什么要使用动态存储器分配
    • 程序使用动态存储器分配的最重要的原因是经常直到程序实际运行时,它们才知道某些数据结构的大小。
    • 最简单的方法就是用某种硬编码的最大数组大小静态地定义这个数组。
      一种更好的方法是在运行时,在己知了 n 的值之后,动态地分配这个数组。使用这种方法,数组大小的最大值就只由可用的虚拟存储器数量来限制了。

    垃圾收集

    • 应用通过调用 malloc 和 free 来分配和释放堆块。应用要负责释放所有不再需要的已分配块。
    • 垃圾收集器 (garbage collector) 是一种动态存储分配器,它自动释放程序不再需要的己分配 块。这些块称为垃圾 (garbage) 。
    • 自动回收堆存储的过程叫做垃圾收集 (garbage collection)。在一个支持垃圾收集的系统中,应用显式分配堆块,但是从不显示地释放它们。在 C 程序的上下文中,应用调用 malloc,但是从不调用 free。反之,垃圾收集器定期识别垃圾块,并相应地调用 free,将这些块放回到空闲链表中。

    教材学习中的问题和解决过程

    C 程序中常见的与存储器有关的错误

    • 间接引用坏指针
      在进程的虚拟地址空间中有较大的洞,没有映射到任何有意义的数据。如果我们试图间接引用一个指向这些洞的指针,那么操作系统就会以段异常中止 我们的程序。而且,虚拟存储器的某些区域是只读的。试图写这些区域将会以保护异常中止这个程序。

    • 读未初始化的存储器
      常见的错误就是假设堆存储器被初始化为零。

    • 允许栈缓冲区溢出
      如果一个程序不检查输入串的大小就写人梳中的目标缓冲 区,那么这个程序就会有缓冲区溢出错误 (buffer overflow bug)。
      必须使用 fgets 函数,这个函数限制了输入串的大小

    • 假设指针和它们指向的对象是相同大小的
      常见的错误是假设指向对象的指针和它们所指向的对象是相同大小的

    • 造成错位错误

    • 引用指针,而不是它所指向的对象
      不太注意 C 操作符的优先级和结合性,我们就会错误地操作指针,而不是指针所指向的对象。

    • 误解指针运算
      忘记了指针的算术操作是以它们指向的对象的大小为单位来进行的,而 这种大小单位并不一定是字节。

    • 引用不存在的变量

    • 引用空闲堆块中的故据
      引用已经被释放了的堆块中的数据

    • 引起存储器泄漏
      存储器泄漏是缓慢、隐性的杀手,当程序员不小心忘记释放已分配块,而在堆里创建了垃圾时,会发生这种问题。
      如果经常调用 leak,那么渐渐地,堆里就会充满了垃圾,在最糟糕的情况下,会占用整个虚拟地址空间。对于像守护进程和服务器这样的程序来说,存储器泄漏是特别严重的,根据定义这些程序是不会终止的。

    小结

    虚拟存储器是对主存的一个抽象。支持虚拟存储器的处理器通过使用一种叫做虚拟寻址的间接形式来引用主存。处理器产生一个虚拟地址,在被发送到主存之前,这个地址被翻译成一个物理地址。从虚拟地址空间到物理地址空间的地址翻译要求硬件和软件紧密合作。专门的硬件通过使用页表来翻译虚拟地址,而页表的内容是由操作系统提供的。
    虚拟存储器提供三个重要的功能:

    1. 它在主存中自动缓存最近使用的存放磁盘上的虚拟地址空间的内容。虚拟存储器缓存中的块叫做页。对磁盘上页的引用会触发缺页,缺页将控制转 移到操作系统中的一个缺页处理程序。缺页处理程序将页面从磁盘拷贝到主存缓存,如果必要, 将写回被驱逐的页。
    2. 虚拟存储器简化了存储器管理,进而又简化了链接、在进程间共享数 据、进程的存储器分配以及程序加载。
    3. 最后,虚拟存储器通过在每条页表条目中加人保护位,从而了简化了存储器保护。
      地址翻译的过程必须和系统中所有的硬件缓存的操作集成在一起。大多数页表条目位于L1 高速缓存中,但是一个称为 TLB 的页表条目的片上高速缓存, 通常会消除访问在L1上的页表条目的开销。
      现代系统通过将虚拟存储器片和磁盘上的文件片关联起来,以初始化虚拟存储器片,这个过程称为存储器映射。存储器映射为共享数据、创建新的进程以及加载程序提供了一种高效的机制。应用可以使用 mmap 函数来手工地创建和删除虚拟地址空间的区域。然而, 大多数程序依赖 于动态存储器分配器,例如 malloc,它管理虚拟地址空间区域内一个称为堆的区域。动态存储器分配器是一个感觉像系统级程序的应用级程序,它直接操作存储器,而无需类型系统的很多帮助。分配器有两种类型。显式分配器要求应用显式地释放它们的存储器块。隐式分配器(垃圾收集器)自动释放任何未使用的和不可达的块。
      管理和使用虚拟存储器是一件困难和容易出错的任务。常见的错误示例包括:
      间接引用坏指针,
      读取未初始化的存储器,
      允许找缓冲区溢出,
      假设指针和它们指向的 对象大小相同,
      引用指针而不是它所指向的对象,
      误解指针运算,
      引用不存在的变量,
      引起存储器泄漏。

    学习进度条

    尝试一下记录「计划学习时间」和「实际学习时间」,到期末看看能不能改进自己的计划能力。这个工作学习中很重要,也很有用。
    耗时估计的公式
    :Y=X+X/N ,Y=X-X/N,训练次数多了,X、Y就接近了。

    参考:软件工程软件的估计为什么这么难软件工程 估计方法

    • 计划学习时间:XX小时

    • 实际学习时间:XX小时

    • 改进情况:

    (有空多看看现代软件工程 课件
    软件工程师能力自我评价表
    )

    参考资料

  • 相关阅读:
    [转]游戏开发指南
    [转]C++接口定义及实现举例
    [转]关于模板函数/模板类编译成DLL
    [转]游戏程序员要求
    [转]如何定位Release程序崩溃原因
    [转]对0基础MFC者的一点建议
    [转]链接警告 LNK4098
    动态调用WCF
    动态添加删除WCF服务类包
    将Xaml文档转成XPS文档[转]
  • 原文地址:https://www.cnblogs.com/hpl20155329/p/7967827.html
Copyright © 2011-2022 走看看