内存管理<原理篇>(四、分段和分页)

2023-11-09

4.1 分段

在上一篇已经介绍了交换和分区,不管是交换还是分区,都有提到,我们需要把进程加载到内存中,然后再运行,那进程是怎么加载进内存的呢?是整个进程都一起加载么?

看过上一篇的都了解,按照上一篇的技术是很有可能整个进程一起加载,不过现在操作系统应该不这样做了,现在操作系统引入的是分段,如果看过编译链接的朋友,应该就会恍然大悟,原来我们说的各个程序段是这个意思。

4.1.1 程序段介绍

我们写程序时,我们会认为程序由主程序加上一组方法、函数所构成并且程序还包含各种数据结构:对象、数组、堆栈等。每个模块或函数之间都是通过名字来引用的。

我们经常会说堆栈、变量、C库等,但我们并不知道这些东西存在哪里,也不知道这些东西是怎么存储的。

正因为我们程序有这么多元素,并且各种元素属性不一样,有的只读,有的可读可写,有的可以增长,如果像上一节课一个进程就分配一块内存,这样做缺点很大,所以引进了我们今天的主题,分段。

分段就是支持这种用户视图的内存管理方案。逻辑地址空间是由一组段构成。每个段都有名称和长度。

怎么确定段内的地址?其实只需要<段号, 偏移>就能确定位置,这个下一节详细介绍。

下面我们就来先认识一下,现代计算机代码编译后的各个段,当然现代计算用的是虚拟内存,这个我们后面介绍,先忽略,我们只是来看看各个段的介绍:

root@ubuntu:~/knowledge_systeam/4.os/3.Memory/1.principle/01# objdump -h test

test:     file format elf64-x86-64

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .interp       0000001c  0000000000400238  0000000000400238  00000238  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .note.ABI-tag 00000020  0000000000400254  0000000000400254  00000254  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .note.gnu.build-id 00000024  0000000000400274  0000000000400274  00000274  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .gnu.hash     0000001c  0000000000400298  0000000000400298  00000298  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .dynsym       00000048  00000000004002b8  00000000004002b8  000002b8  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .dynstr       00000038  0000000000400300  0000000000400300  00000300  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  6 .gnu.version  00000006  0000000000400338  0000000000400338  00000338  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  7 .gnu.version_r 00000020  0000000000400340  0000000000400340  00000340  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  8 .rela.dyn     00000018  0000000000400360  0000000000400360  00000360  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  9 .rela.plt     00000018  0000000000400378  0000000000400378  00000378  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 10 .init         0000001a  0000000000400390  0000000000400390  00000390  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 11 .plt          00000020  00000000004003b0  00000000004003b0  000003b0  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 12 .plt.got      00000008  00000000004003d0  00000000004003d0  000003d0  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 13 .text         00000192  00000000004003e0  00000000004003e0  000003e0  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 14 .fini         00000009  0000000000400574  0000000000400574  00000574  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 15 .rodata       00000004  0000000000400580  0000000000400580  00000580  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 16 .eh_frame_hdr 00000034  0000000000400584  0000000000400584  00000584  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 17 .eh_frame     000000f4  00000000004005b8  00000000004005b8  000005b8  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 18 .init_array   00000008  0000000000600e10  0000000000600e10  00000e10  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 19 .fini_array   00000008  0000000000600e18  0000000000600e18  00000e18  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 20 .jcr          00000008  0000000000600e20  0000000000600e20  00000e20  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 21 .dynamic      000001d0  0000000000600e28  0000000000600e28  00000e28  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 22 .got          00000008  0000000000600ff8  0000000000600ff8  00000ff8  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 23 .got.plt      00000020  0000000000601000  0000000000601000  00001000  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 24 .data         00000011  0000000000601020  0000000000601020  00001020  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 25 .bss          00000007  0000000000601031  0000000000601031  00001031  2**0
                  ALLOC
 26 .comment      00000035  0000000000000000  0000000000000000  00001031  2**0
                  CONTENTS, READONLY

现代操作系统也是把程序分了这么多个段,前面是段号,Size是段的大小。

其中我们最熟悉的13 .text 代码段;24 .data 数据段。

这两个段,以后讲虚拟内存还会回来介绍的。

4.1.2 各段放入内存信息

上面我们见识到了,一个程序分了这么多个段,每个段都各自加载到内存中,内存是怎么申请的呢?

就是上一篇写的分区,通过连续内存分区分配的方式给程序中各个段分配内存。(虽然我们上一节课说了分区分配很多缺点,但是也是需要了解一下,并且在下面会提出解决分区分配缺点的方案)

在这里插入图片描述

这个图就是分段后,进程加载进内存的部署,当然现在操作系统使用的虚拟内存并不是这样(不过也差不多了),不过我们暂时先看看之前是怎么处理的,怎么演变过来的。

我们也随便看看现在操作系统进程加载进内存的分布:

root@ubuntu:/proc/1604# cat maps 
00400000-00401000 r-xp 00000000 08:01 12460229                           /root/knowledge_systeam/4.os/3.Memory/1.principle/01/test
00600000-00601000 r--p 00000000 08:01 12460229                           /root/knowledge_systeam/4.os/3.Memory/1.principle/01/test
00601000-00602000 rw-p 00001000 08:01 12460229                           /root/knowledge_systeam/4.os/3.Memory/1.principle/01/test
7f9c3cb34000-7f9c3ccf4000 r-xp 00000000 08:01 791097                     /lib/x86_64-linux-gnu/libc-2.23.so
7f9c3ccf4000-7f9c3cef4000 ---p 001c0000 08:01 791097                     /lib/x86_64-linux-gnu/libc-2.23.so
7f9c3cef4000-7f9c3cef8000 r--p 001c0000 08:01 791097                     /lib/x86_64-linux-gnu/libc-2.23.so
7f9c3cef8000-7f9c3cefa000 rw-p 001c4000 08:01 791097                     /lib/x86_64-linux-gnu/libc-2.23.so
7f9c3cefa000-7f9c3cefe000 rw-p 00000000 00:00 0 
7f9c3cefe000-7f9c3cf24000 r-xp 00000000 08:01 791108                     /lib/x86_64-linux-gnu/ld-2.23.so
7f9c3d116000-7f9c3d119000 rw-p 00000000 00:00 0 
7f9c3d123000-7f9c3d124000 r--p 00025000 08:01 791108                     /lib/x86_64-linux-gnu/ld-2.23.so
7f9c3d124000-7f9c3d125000 rw-p 00026000 08:01 791108                     /lib/x86_64-linux-gnu/ld-2.23.so
7f9c3d125000-7f9c3d126000 rw-p 00000000 00:00 0 
7ffe32b26000-7ffe32b47000 rw-p 00000000 00:00 0                          [stack]
7ffe32ba9000-7ffe32bac000 r--p 00000000 00:00 0                          [vvar]
7ffe32bac000-7ffe32bae000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

也是一个段占一块内存,不过因为有虚拟内存的存在,每个段的地址都知道了,不过之前的系统在没有虚拟内存的情况下,每个段的地址和段号是根据段表来决定的,并且如果程序的运行也离不开段表。

下面我们就来了解了解段表。

4.1.3 段表

因为我们分了很多个段,并且每个段都有不同的基地址,这样的结构让我们想起了表。

计算机也引入了一张这样的表,叫段表。段表的每个条目都有段号、段基地址、段界限

段基地址包含该段在内存中开始物理地址,逻辑地址映射成物理地址有用。

段界限指该段的长度,一般做保护处理,怕访问溢出。(这个可以看前面章节)

接下来我们就按哈工大老师说的例子,我们来过一边重定位:

mov [DS:100], %eax
jmpi 100, CS
段号 基地址 长度 保护
0 180K 150K R
1 360K 60K R/W
2 70K 110K R/W
3 460K 40K R

问题:假设DS=1,CS=0,上面两条指令运行时重定位成什么?

DS=1,说明这个数据段在1号段,1号段的基地址为360K,段内偏移是100,所以我们要把这个内存里的数据:360K+100,赋值到eax寄存器中。

CS=0,说明这个指令段在0号段,0号段的基地址为180K,段内便宜也是100,所以我们要跳到180K+100的指令上,然后继续执行。

4.1.4 总结

我们引入分段之后,跟之前执行程序的最大区别是,之前只有一个重定位寄存器即可,因为都是一个段,只有一个基地址加偏移就可以了,现在分了很多个段,自然就需要段表了,所以执行程序的时候多了一步查找过程。

现代操作系统其实有一个GDT和LDT表,跟上面的段表比较相似了,GDT表示操作系统标记每个进程的地址的,LDT表示每个进程中各个段的地址,有点跟段表相似了,之后再分析这两个。

4.2 分页

4.1介绍的分段是对程序的划分,并且也是对逻辑地址的划分,并且通过分区分配的方式加载进程的各个段,上一篇也介绍了分区方式的缺点,所以分区的方式是操作系统早期对物理内存的划分。那现在操作系统对内存是如何划分的???

没错,现代操作系统对物理内存的划分是分页。那啥是分页呢???

上一篇我们用了分面包来介绍分区,那大家想想现在分面包是怎么分的???

现在的面包是分片,每个人的胃口都不一样,胃口大的就吃多几片,胃口小的就吃小就吃一片,这样浪费就不会那么多,内存的分页也是这种思想,没页大小是4KB,当然也有其他的大小。

下面我们就来看看是怎么使用分页的。

4.2.1 概念介绍

分页是将物理内存分为固定大小的块,称为帧、页帧或页框。每个页框(帧、页帧)都有一个编号,叫做页框号(帧号、页帧号),也框号是从0开始的。

将逻辑内存(是否想起之前说的地址空间的抽象)也分为跟页框大小一样的块,称为页或页面。每个页面也有一个编号,叫页号,页号也是从0开始。

4.2.2 各段加载进内存

前面感受了分段的时候,一整块加入内存,那现在物理内存引入了分页,我们就来感受一下分页吧。

在这里插入图片描述

这样为了画少一点,我把一页设为512K,其中代码段为1M,刚好占了两页,数据段512k也刚好一页,然后堆段只有612k,但是也需要占两也,其中剩下的就是内部碎片,因为我这里分的页大,所以内部碎片也很大,其实实际系统大部分都只分4k作为一页,即使有内部碎片也影响不大,栈段也是1M,刚好2页。

最后存在物理内存中,也是离散的,这就是分页的好处,不用一起申请那么大的内存。所以可以离散存储。但是也因为这种离散存储,导致我们指令寻找不到物理地址,那这里也再次引入页表的概念。

页表其实跟上面说的段表差不多,也是通过页号了找到对应的物理地址。

4.2.3 例子分析

那逻辑地址是怎么找到物理地址的,我们来研究一下。

例子还是看哈工大老师举的例子:

mov [0x2240], %eax  // 逻辑地址
页号 页框号 保护
0 5 R
1 1 R/W
2 3 R/W
3 6 R

我们的页就按4K来计算。

逻辑地址为0x2240,那它的

页号= 0x2240 / (4 *1024) = 0x02

页偏移 = 0x2240 % (4 *1024) = 0x240

通过查找页表,页号为2的,页框号为3,页框号为3的话,基地址为0x03 * 4 * 1024 = 0x3000

最后再加上偏移,最终物理地址 = 0x3000 + 0x240 = 0x3240

4.2.4 总结

我们这一篇学习了程序分段,物理内存分页,也就是段页式初步学习,一个程序的执行,需要先查段表,查出段表中的基地址,然后计算出当初指令或数据的逻辑地址,然后再根据逻辑地址计算出在哪一页,然后通过页号去查页表,最后才找到具体的物理地址,这样确实麻烦了不少。不过后期虚拟内存的引进就少了一层,下一篇我们主要学习页表,快接近真想了,加油。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

内存管理<原理篇>(四、分段和分页) 的相关文章

  • Redis 学习笔记(十一)基数统计(HyperLogLog)

    Redis 学习笔记 十一 基数统计 HyperLogLog 1 介绍 HyperLogLog命令是redis在2 8版本中加入的 Redis中HyperLogLog是用来做基数统计的 HyperLogLog 的优点是 在输入元素的数量或者
  • Java(七) 句柄

    在学习什么是句柄之前我们先学习虚拟机的对对象的访问方式 一 句柄访问方式 使用句柄访问对象 会在堆中开辟一块内存作为句柄池 句柄中储存了对象实例数据 属性值结构体 的内存地址 访问类型数据的内存地址 类信息 方法类型信息 对象实例数据一般也
  • free vs delete简洁版

    free释放的是指针指向的内存 回归到操作系统的空闲内存链表中 之后还需要程序员手动将对应的指针赋值成为NULL 不然那个指针还在 并且还指向那个内存 delete是调用的是对应的new 的变量的析构函数 delete对应new delet
  • Java内存区域(栈、堆、方法区)详细解说

    参考文献 深入学习java虚拟机 概览 java虚拟机在执行java程序的过程中会把它所管理的内存划分成若干个不同的数据区域 这些区域各有用途 以及创建和销毁的时间 有的区域随着虚拟机的进程的启动而存在 有的则依赖用户线程的启动和结束而建立
  • Android Bitmap加载内存占用彻底分析

    背景 在某个版本应用上线后 偶然测得首页占用的内存非常的大而且一直不能回收掉 经过一轮的排查后最终确定是3张图片引起的 当时每张图片占用了将近20m内存 当时紧急处理好后还一直惦记着此事 后来对Android加载Bitmap的内存占用作了彻
  • 内存四区(代码区 静态区 栈区 堆区)

    参考 内存四区 代码区 静态区 栈区 堆区 作者 今天天气眞好 发布时间 2021 04 01 18 09 13 网址 https blog csdn net qq 51118175 article details 115379779 sp
  • 频繁读写文件导致内存使用率过高

    最近接到一个客户反馈 说是服务器内存使用过高 总内存16G 使用top命令查看可用内存已经不足1G了 客户环境服务器为linux 部署了3个tomcat 每个tomcat均有大量的日志产生 让客户使用free m检查一下 此处有必要解释一下
  • C++内存泄漏和内存碎片的产生及避免策略

    1 内存泄漏的定义 一般我们常说的内存泄漏是指堆内存的泄漏 堆内存是指程序从堆中分配的 大小任意的 内存块的大小可以在程序运行期决定 使用完后必须显示释放的内存 应用程序一般使用malloc realloc new等函数从堆中分配到一块内存
  • c++ 获取磁盘总大小

    float WindowsInfo GetDiskTotal 单位 G all Total 0 函数外自定义 all Free 0 DWORD dwSize MAX PATH TCHAR szLogicalDrives MAX PATH 0
  • System.Single

    浮点 类型 别名 float System Single double System Double decimal System Decimal 字符 类型 别名 允许的值 bool System Boolean true flase ch
  • Linux 内存管理

    文章目录 前言 连续分配 单一连续分配 分区式分配 固定分区分配 动态分区分配 可重定位分区分配 离散分配 分段 分页 多级页表 快表 TLB 段页式 Linux 前言 Linux 内存管理 虚拟内存管理 虚拟内存空间 虚拟内存分配 Lin
  • 在WPF中获取程序的专用工作集内存 PerformanceCounter

    使用 PerformanceCounter 获取程序的专用工作集内存并不难 但是就是得找一下属性 通过 CategoryName 遍历 InsanceName 再通过它们遍历 CounterName 之后通过这三个属性得到我们想要的内存 p
  • java虚拟机运行时分布区域

    概述 本文将从概念上介绍java虚拟机内存的各个区域 讲解这些区域的作用 服务对象以及其中可能产生的问题 运行时数据区域 java虚拟机所管理的内存将会包括以下几个运行时数据区域 程序计数器 程序计数器是一块较小的内存空间 它可以看作是当前
  • 【Linux】Linux中Swap与Memory内存简单介绍

    背景介绍 对于Linux来说 其在服务器市场的使用已经占据了绝对的霸主地位 不可动摇 Linux的各种设计思想和使用也被传承 当然不乏各种黑Linux 而且黑的漂亮 Linux的很多独特的设计 对性能也产生了巨大的提升 也为其他应用软件和系
  • [指针五]指针做参数传递--使用详解

    void myMalloc char s 我想在函数中分配内存 再返回 s char malloc 100 void main char p NULL myMalloc p 这里的p实际还是NULL p的值没有改变 为什么 if p fre
  • CPU高速缓存SRAM命中问题的总结与实验

    1 SRAM高速缓存的结构 获取本机CPU的SRAM缓存信息 我使用的是一个叫cpuinfo x86的小程序 可以获取x86架构的cpu相关信息 下载地址 http osxbook com book bonus misc cpuinfo x
  • 怎么计算union和struct中字节数计算

    首先我的运行结果都是在64位系统的Xcode中运行的 然后 这个只是由于对于标准的位移量方法看得头疼 自己总结出来的 如果有错误或者不明欢迎留言 字节 一般成8位为一个字节 在Xcode中sizeof int 等于4 在这里也就采用int占
  • 程序员思维模式 - 主调试循环

    文章目录 主调试循环 验证在图层中进行 优化循环时间 为什么快速循环更好 短循环时间是通用的吗 一些综合测试是必要的 复杂性是否会导致测试验证循环 救援的暂存环境 结论 仅通过测试进行验证基本上是在仪器上驾驶飞机 而不是能够向外看挡风玻璃
  • C/C++内存泄漏与检测

    该死系统存在内存泄漏问题 项目中由于各方面因素 总是有人抱怨存在内存泄漏 系统长时间运行之后 可用内存越来越少 甚至导致了某些服务失败 内存泄漏是最难发现的常见错误之一 因为除非用完内存或调用malloc失败 否则都不会导致任何问题 实际上
  • 作用域和内存问题

    文章目录 一 基本类型和引用类型的值 基本类型和引用类型的区别 1 动态的属性 2 复制变量值 3 传递参数 4 监测类型 二 执行环境及作用域 1 延长作用域链 2 没有块级作用域 一 基本类型和引用类型的值 变量可能包括两种不同的数据类

随机推荐

  • 【图像】焦距与景深的关系

    在光圈恒定 被摄物体在取景框内大小恒定的前提下 焦距与景深成反比关系 即焦距越长 景深越浅 反之亦然 当焦距越长时 成像的前虚后实 即浅景深 效果会越明显 被摄物清晰但周围环境模糊 当焦距越短时 成像的前虚后实 即深景深 效果会越小 被摄物
  • 开源项目:如何选择、使用以及二次开发?

    软件开发领域有一个流行的原则 DRY Don t repeat yourself 翻译过来更通俗易懂 不要重复造轮子 开源项目的主要目的是共享 其实就是为了让大家不要重复造轮子 尤其是在互联网这样一个快速发展的领域 速度就是生命 引入开源项
  • word2vec思考:word2vec为什么不使用非线性激活函数?

    word2vec不是为了做语言模型 它不需要预测得更准 另外 不使用非线性激活函数可以使函数更简单 加快网络训练 也会使训练出来的词大量线性相关 这正是我们需要的
  • Python常用数据类型(表达式、语句、函数、关键字、变量、字符串)总结

    1 个概念 1 1 表达式 表达式 是由数字 算符 数字分组符号 括号 由变量和约束变量等 以能求得数值的有意义排列 法所得的组合 表达式特点 表达式 般仅仅 于计算 些结果 不会对程序产 实质性的影响 如果在交互模式中输 个表达式 解释器
  • matlplotlib绘图 之 函数legend()

    一 添加图例的两种方法 来自 https www cnblogs com kuangkuangduangduang p 10300506 html 1 推荐使用 在plot函数中增加label参数 然后在后面加上plt legend 不加p
  • 正点原子IMX6ULL阿尔法USB摄像头的远程调用(三)USB摄像头的连接与使用

    终于轮到摄像头了 IMX6ULL支持USB摄像头 直接插在USB口上就可以了 不过 下面介绍的方案要在Python中调用USB摄像头的数据 所以在IMX6ULL中需要移植MJPG Streamer 这个不太难 百度一下就OK 迅为的方案就可
  • HashMap工作原理

    HashMap是一个key value键值对的数据结构 它是由数组 链表 红黑树的形式实现的 默认长度是16 只能有一个key为null 可以有多个value为null 数组是一个个Node 数组 我们叫它hash桶数组 它上面存放的是ke
  • 上采样方法

    目录 上采样 Upsampling 方法 去池化 最近邻方法 钉床方法 最大去池化 双线性插值 反卷积 膨胀卷积 上采样 Upsampling 方法 上采样 是指将低分辨率的图像或特征图放大到原始分辨率的过程 在计算机视觉中 上采样通常用于
  • Bug的级别,按照什么划分

    Bug分类和定级 一 bug的定义 二 bug的类型 三 bug的等级 四 bug的优先级 一 bug的定义 一般是指不满足用户需求的则可以认为是bug 狭义指软件程序的漏洞或缺陷 广义指测试工程师或用户提出的软件可改进的细节 或与需求文档
  • CodePush 私有化部署

    安装 NodeJs 和 Npm 下载安装 NodeJs 安装 nodejs wget https nodejs org dist v6 9 4 node v6 9 4 tar gz configuremakemake install 安装
  • SIM卡与IEC 7816

    SIM卡与IEC 7816 SIM Subscriber Identification Module 又被称为用户身份识别卡 智能卡 SIM卡是一种物理载体 而相关的性能以及协议的规定都包含在IEC 7816协议中 IEC 7816规范 物
  • HJ103 Redraiment的走法 —— 华为机考练习题

    一 题目 描述 Redraiment是走梅花桩的高手 Redraiment可以选择任意一个起点 从前到后 但只能从低处往高处的桩子走 他希望走的步数最多 你能替Redraiment研究他最多走的步数吗 数据范围 每组数据长度满足 1 le
  • ag-grid-vue的配置

    public get gridOptions GridOptions const that this return headerHeight 30 表头高度 rowHeight 30 行高 columnDefs 列定义 headerName
  • 常用JS对象的方法总结

    String 方法 描述 charAt 返回在指定位置的字符 charCodeAt 返回在指定的位置的字符的 Unicode 编码 concat 连接字符串 indexOf 检索字符串 match 找到一个或多个正则表达式的匹配 repla
  • spring的后处理

    什么是spring的后处理器 spring的后处理是spring对开开发的重要扩展点 bean的许多的功能的增强就是通过后处理实现的 他可以允许我们产于到bean的实例化路程中去 两类后处理器 根据我们对于bean的实例化的认识 我们知道b
  • C中调用带参数的exe并接收返回值

    test exe c sharp view plain copy include
  • 高等数学知识点总结

    高等数学知识点总结 一 间断点 定义 1 f x 在处没有定义 则为间断点 2 f x 在处有定义 但是极限不存在 3 f x 在处有定义 极限也存在 但是不相等 分类 第一类间断点 左右极限都存在 1 可去间断点 2 跳跃间断点 第二类间
  • Android Service

    http www cnblogs com lwbqqyumidi p 4181185 html Service通常总是称之为 后台服务 其中 后台 一词是相对于前台而言的 具体是指其本身的运行并不依赖于用户可视的UI界面 因此 从实际业务需
  • 微信小程序使用wxParse解析html

    转 http www jianshu com p 3de027555e77 最近项目上遇到在微信小程序里需要显示新闻内容 新闻内容是通过接口读取的服务器中的富文本内容 是html格式的 小程序默认是不支持html格式的内容显示的 那我们需要
  • 内存管理<原理篇>(四、分段和分页)

    文章目录 4 1 分段 4 1 1 程序段介绍 4 1 2 各段放入内存信息 4 1 3 段表 4 1 4 总结 4 2 分页 4 2 1 概念介绍 4 2 2 各段加载进内存 4 2 3 例子分析 4 2 4 总结 4 1 分段 在上一篇