当前位置: 首页 > news >正文

wordpress 网站统计插件下载贵德网站建设

wordpress 网站统计插件下载,贵德网站建设,中国建设门户网登录入口,一个空间怎么做多个网站1.程序地址空间分配回顾 在前⾯C语⾔以及C部分介绍过⼆者的内存分配如下图所示#xff1a; 全局变量区和未初始化全局变量区也被称为数据区#xff0c;数据区中除了有全局变 量#xff0c;还有静态变量和常量 使⽤下⾯的代码演示不同的内容所处的地址#xff1a; #includ…1.程序地址空间分配回顾 在前⾯C语⾔以及C部分介绍过⼆者的内存分配如下图所示 全局变量区和未初始化全局变量区也被称为数据区数据区中除了有全局变 量还有静态变量和常量 使⽤下⾯的代码演示不同的内容所处的地址 #include stdio.h #include unistd.h #include stdlib.h// 初始化的全局变量 int global 0; // 未初始化的全局变量 int value;int main() {// 环境变量char* envi getenv(PWD);// 堆区int* ptr (int*)malloc(sizeof(int)*10);// 栈区int a 0;int b 0;int c 0;printf(%p\n, global);printf(%p\n, value);printf(%p\n, ptr);// 代码区printf(%p\n, main); // 函数名即函数地址printf(%p\n, envi);printf(%p\n, a);printf(%p\n, b);printf(%p\n, c);return 0; }输出结果 0x601048 0x60104c 0x7e1010 0x4005cd 0x7ffc99757f43 0x7ffc9975694c 0x7ffc99756948 0x7ffc99756944 实际上所谓的程序地址空间就是进程地址空间进程地址空间是如何产⽣的就是下 ⾯需要探讨的问题 2.进程地址空间 2.1.虚拟地址 前⾯提到⽗进程和⼦进程会共享代码和数据尤其是两个进程不进⾏数据修改时 数据不会产⽣两份那么这样理解就可以直观地认为当⼦进程修改了数据对应的变 量内存地址就会发⽣改变但是改变的是不是程序读取到的地址看下⾯例⼦的演示 结果 #include stdio.h #include unistd.h #include stdlib.h// 初始化的全局变量 int global 0; // 未初始化的全局变量 // int value;int main() {printf(父进程, pid %d, global %p\n, getpid(), global);pid_t p fork();if(p 0) {// 子进程while(1) {printf(子进程, pid %d, global %p\n, getpid(), global);// 子进程修改global;sleep(1);}} else {while(1) {}}return 0; }输出结果 父进程, pid 12969, global 0x601050 子进程, pid 12970, global 0x601050 可以看到尽管⼦进程修改了与⽗进程共享的代码中的变量⼦进程读取到的变量的 地址与⽗进程读取到的变量的地址是完全相同的。 实际上在C语⾔程序中使⽤ 获取到的地址是⼀个虚拟地址也称线性地址对 应虚拟地址的就是物理地址。 在上⾯提到的「⼦进程改变代码中的数据对应的内存地址会发⽣改变」本质是因 为此处的内存地址指的是物理地址⽽不是虚拟地址 2.2.地址空间 地址空间可以理解为是操作系统为每⼀个进程开辟的⼀块运⾏空间示意图如下 为了保证所有的进程都有⼀个完整的地址空间操作系统为每个进程提供⼀个独⽴的 虚拟地址空间。例如如果操作系统⽀持3GB的虚拟地址空间每个进程都会认为⾃ ⼰拥有独⽴的3GB空间不会受到其他进程占⽤内存的影响。这⼀过程暂且可以理解 为操作系统为每⼀个进程“画的⼀张⼤饼”⽽这个“饼”即为进程地址空间 2.3.区域划分 进程地址空间中存在着多个区域每⼀个区域有着⾃⼰的作⽤。每⼀块区域的划分实 际上是根据区域的起始值和终⽌值进⾏决定示意图如下 为了⽅便管理在Linux中操作系统在底层的 task_struct 内部存在着⼀个结构 体指针该结构体指针的类型是 mm_struct 结构体该结构体中存在着⼀些变量⽤ 于存储指定区域的起始值和终⽌值。这些值本质也是地址值但是这个地址并不是实 际的物理内存的地址⽽是通过映射后的虚拟地址源码如下 struct mm_struct {// ...unsigned long start_code, end_code, start_data, end_data;unsigned long start_brk, brk, start_stack;unsigned long arg_start, arg_end, env_start, env_end;unsigned long rss, total_vm, locked_vm;// ... }; 因为变量的地址都是在这些指定的进程地址空间区域中所以也可以解释为什么程序 获取到的是虚拟地址⽽⾮物理地址 解释 3.分页与数据独立 在上⾯探讨了虚拟地址和物理地址操作系统为了管理这两个地址之间的映射从⽽ 保证虚拟地址能够正确访问到实际的物理地址对应的内容在创建⼀个进程PCB时会 同时创建⼀个⻚表。 在执⾏前⾯的代码的过程中⼦进程未创建之前⽗进程拥有⾃⼰的⻚表和进程地址 空间此时全局变量 global 会由操作系统在物理地址上开辟⼀块空间并将映射后 的虚拟地址填充到⻚表中被进程获取如下图所示 当创建⼦进程之后⼦进程会与⽗进程共享代码和数据此时意味着⼦进程拷⻉⽗进 程中的 task_struct 和⻚表对 task_struct 中的内容进⾏针对性地修改在⼦进 程没有改变复制过来的数据之前由于⻚表内容相同所以⼦进程⻚表中的映射与⽗ 进程完全相同示意图如下 当⼦进程对 global 变量进⾏修改时操作系统就会在物理内存中开辟⼀块新的空 间将共享的 global 数据拷⻉到该空间这个拷⻉的过程也被称为写时拷⻉。物理 内存虽然开辟了⼀块新的空间实际上对于⼦进程的⻚表来说还是通过同样的虚拟 地址映射物理地址 上⾯的过程也就可以解释为什么最开始的代码中⼦进程和⽗进程获取到的变量值不 同但是地址却相同也就更加验证了⼀个变量中不可能存在两个不同的值 4.页表基本介绍 在Linux中⻚表不仅仅有虚拟地址和物理地址的映射还有物理地址的属性 RWX 以 及是否有数据的标识 isExists 所以更加细致的⻚表应该如下所示 RWX 属性代表虚拟地址对应的物理地址是否具有读R、写W和执⾏权限 X。 前⾯提到每⼀个进程地址空间区域都由指定的起始值和终⽌值进⾏划分⽽这些区 域有的是可以写有的不可以写只能读但是对于物理内存来说绝⼤部分的空间都 是可以写的所以对于限制指定的物理地址是否可以写⼊就是通过 RWX 属性进⾏控制 例如前⾯学习到的栈区和堆区在程序代码运⾏时可以在栈区和堆区申请空间并 进⾏写⼊但是对于字符串常量等具有常性的值就不可以进⾏随意修改和写⼊。⽽之 所以在语⾔层⾯⽆法检测到这种问题原因就是⻚表并不是在编译期间就创建的⽽ 是在程序运⾏开始由操作系统创建但是为了语⾔层⾯更加容易看出这种错误就可 以把不想被修改的内容或者本身不可以修改的内容修饰为 const 从⽽让编译器可 以在编译器检查出错误 此刻也便可以解释为什么程序会有野指针的概念在语⾔层⾯野指针表示指针中的 地址对应的空间已经被释放并归还给操作系统进⾏管理此时不可以通过这个指针访 问对应的地址。在此时的系统层⾯之所以可以限制野指针写⼊就是通过 RWX 属性 因为虚拟地址对应的物理地址具有的属性已经是R isExists 属性代表虚拟地址对应的物理地址是否存在有效数据。在操作系统加载 进程时会创建对应的进程地址空间和⻚表在⻚表中将虚拟地址和物理地址进⾏映 射。然⽽这个过程中某些进程的代码可能特别多导致正⽂代码区占⽤的空间变得 很⼤⽽实际使⽤时可能有很⼤⼀部分的代码⻓时间不会被执⾏造成资源浪费。 为了解决这个问题操作系统通常采⽤按需加载惰性加载Lazy Loading策 略。操作系统会先加载⼀部分内容在运⾏过程中通过检查⻚表中的有效位 Valid Bit来判断虚拟地址访问的物理地址是否已经加载。如果没有加载则 触发缺⻚中断Page Fault操作系统会从磁盘加载相应的数据到内存中再继 续执⾏。这⼀过程也适⽤于交换分区Swap Partition决定何时将数据换⼊ 或换出内存 结合前⾯的两个属性操作系统就实现先告诉进程⾃⼰已经开辟好了空间这个空间 的地址由多个虚拟地址组成但是实际上可能物理地址并没有全部与指定的虚拟地址 对应当程序运⾏到指定的部分再进⾏开辟映射这个操作就可以实现将内存空间利 ⽤率最⼤化 5.缺页中断与写时拷贝 前⾯提到当⼦进程修改了⽗进程的共享变量就会发⽣写时拷⻉实际上在这之前 需要进⾏⼀系列的操作检测 当⽗进程开始运⾏⼦进程还未被创建之前⽗进程的代码区为只读但是数据区是 默认为读写的当⼦进程创建后代码区依旧是只读但是⼆者的数据区均变为只 读⼦进程从创建的位置开始执⾏代码因为⼦进程会拷⻉ task_struct 中有关程 序计数器部分的内容此时⽗⼦进程都只是读取对应代码区和数据区的数据实现数 据和代码共享 注意 此处之所以⼦进程不额外直接拷⻉⽗进程的数据尽管将来可能要对数据进⾏ 修改是因为可能⽗进程的数据很⼤但是⼦进程需要修改的数据很⼩如果在创建 ⼦进程时就将数据拷⻉此时就会导致空间的浪费 当⼦进程准备修改数据时因为数据区已经变为只读⼦进程想要修改就会修改失 败此时就会触发缺⻚中断错误。但是因为缺⻚中断错误发⽣的原因不只有⼀种还 有可能是野指针写⼊等情况所以此时系统需要检测是否是误操作。当系统检测到数 据区本身是读写的但是现在被设置为只读时就会认为需要发⽣写时拷⻉ 判定完需要进⾏写时拷⻉时系统就会在物理内存中申请空间将原始数据拷⻉到新 空间并对⽗进程和⼦进程的数据区修改为只读⽗进程和⼦进程代码继续执⾏ 这个过程中涉及到原始数据拷⻉⽽不是简单开辟空间使⽤等待⼦进程使⽤新数 据进⾏覆盖是因为可能⼦进程对数据的修改是基于原数据的例如变量⾃增⾏为等 上述过程简略示意图如下 ⼦进程修改数据 6.进程地址空间结构初始化时机 任何⼀个结构体在创建时⼀定要进⾏初始化⽽进程地址空间也是由⼀个结构进⾏描 述这个结构的初始化由操作系统在可执⾏程序加载到内存时完成可执⾏程序加载 到内存变成进程时操作系统可以获取到部分区域的起始值和终⽌值例如正⽂代码 区、数据区包括全局变量区、常量区、静态变量区和命令⾏与环境变量区。所以 这就可以解释为什么静态变量、全局变量和常量⼀直持续到进程结束 但是这其中有两个不同的区域栈区和堆区栈区在函数创建时会开辟对应的栈帧 堆区在申请时会在已有的堆区上额外开辟需要的空间所以这两个区域在程序刚加载 到内存时是不存在的 7.总结 之所以需要存在⻚表和进程地址空间有以下三个原因 1. 保护内存如果让进程直接访问物理内存会导致在物理层⾯的野指针情况 并且这个情况在物理层⾯并不容易被发现和阻⽌ 2. 存在⻚表可以达到进程管理和内存管理耦合度降低因为⻚表主要作⽤的是虚 拟地址和物理地址之间的映射操作系统在创建进程时初始化对应的虚拟地址 即可但是虚拟地址是否有对应的物理地址可以不⽤关⼼只要没有被使⽤。 ⽽对于内存管理操作系统只需要考虑在需要的时候将物理地址加载到⻚表 此时对应的虚拟地址有映射就可以正常执⾏在不需要的时候将物理地址设 置为只读或者给其他进程使⽤ 3. 让进程以统⼀的视⻆看待物理内存⽆序变有序因为操作系统会为每⼀个 进程开辟⼀个独⽴的⻚表和进程地址空间让每⼀个进程都认为⾃⼰拥有操作 系统分配的全部内存空间并且在进程访问地址空间时实际上这个地址空间 的地址是⼀个虚拟地址这个虚拟地址可以由操作系统⾃主决定为连续地址 此时就可以不⽤考虑物理地址是否需要连续因为进程只能获取到虚拟地址 只要虚拟地址有物理地址映射并且拥有指定的权限就不会出现问题从⽽实 现让「让⽆序的物理内存地址变为有序的地址」 物理地址在开辟时⼀般也会尽量是连续开辟保证CPU在缓冲中的数据命中率
http://www.hkea.cn/news/14374044/

相关文章:

  • 外贸公司英文网站内网做网站需要空间吗
  • 南京网站建设小程上海备案证查询网站查询网站查询系统
  • 响应式网站模板免费下载直播开放平台入驻
  • 天津网站建设内容wordpress外贸主题制作
  • 专业网站建设分为8步深圳建设交易中心网站
  • 网站设计软件microsoft2013搜索引擎网络排名
  • 有没有免费做物流推荐的网站域名买好了怎么建网站
  • 希尔顿酒店网站建设的优点h5页面制作软件下载下来要钱吗
  • 网站总体规划说明网站开发基础培训
  • gta手机网站大全制作网页中的链接怎么弄
  • 平凉市住房和城乡建设厅网站云南凡科建站
  • php 网站迁移个性化定制网站有哪些
  • 免费旅行社网站模板企业网站的建立的目的
  • 网站开发合同 黑客攻击条款小型网站开发成本
  • 网站建设怎么弄免费域名注册和免费建站
  • 网站准备建设的内容大气门户网站
  • 腾讯广告投放平台官网网站开发百灵鸟优化
  • 北京西城网站建设公司网站选择理由描述
  • 佛山市住房和建设局网站首页wordpress如何使用简码
  • 雷电模拟器手机版下载官方网站常熟高端网站建设
  • 巧家县住房和城乡建设局网站如何免费学校建网站
  • 重庆建设教育培训管理系统网站网站做淘宝推广收入
  • 深圳专业企业网站建网页访客升级
  • 网站新闻源码网站建设需求精确表
  • 江西通威公路建设集团有限公司网站flash网站开发
  • 电商网站商品表设计Wordpress与dw
  • 做点效果图赚钱的网站桂林市中考信息网官网
  • 海南省住房和建设厅网站网站内容如何优化
  • wordpress站点图片多大合适网站留白
  • 个体户营业执照可以网站备案小企业建网站