文章目录
- 内存
- 一、内存条、总线、DMA
- 二、内存管理
- 1、为什么要有逻辑地址
- 2、逻辑地址和物理地址如何映射
- 3、分页时间和空间优化
- 4、程序内部的内存管理-分段
- 三、内存相关的系统调用
- 1、用户态和内核态
- 四、Java内存
内存
提示:这里可以添加本文要记录的大概内容:
提示:以下是本篇文章正文内容,下面案例可供参考
一、内存条、总线、DMA
- CPU和内存是数据总线和地址总线直接相连
- CPU和显卡是PCIE总线相连
- 南桥中有一个芯片 DMAC(直接内存访问控制器)
- DMAC读取文件时对CUP将总线的控制权交给DMAC ,是绝对的控制权,但是外设依然有效是因为CPU和DMAC 轮换掌握总线控制权(DMA状态下CPU和总线数据隔离状态)
二、内存管理
1、为什么要有逻辑地址
- 程序无法知道可用的物理地址,所有需要做映射
2、逻辑地址和物理地址如何映射
- 固定偏移量映射 : 高效,但是无法估量每个程序具体多大内存 会有内存碎片
- 分页:
- 逻辑内存页(page)
- 页表(page table) 存储 页号和帧号 是逻辑内存和物理内存的关系表(其实还有其他字段,而且每个进程都有属于自己的页表)
- 物理内存祯 (page frame)
内存的一个地址里就是一个字节(Byte)的数据
32位OS物理地址有2^32个,因此只能使用4GB的内存
任何一个32位的程序可操作的逻辑地址是2^32个即4GB(每个32位程序都天真的以为自己拥有4GB内存)
多个程序使用内存总和大于物理内存,此时就会借助磁盘,将并不着急使用的内存放到磁盘,PT对应的帧号只显示是磁盘
- 一次寻址(当寻址对应的帧号是磁盘,会发生缺页中断或缺页异常,然后程序就会进入内核态,最后内核会去磁盘找这一帧的数据,并把它加入到内存中,并再发生一遍寻址,所以速度是可以优化的)
3、分页时间和空间优化
- 时间优化
将最常访问的几个(一般8-128个左右)页表项存到访问速度更快的硬件中,一般实在MMU(内存管理单元),这个小表的名称为TLB,可以称其为快表
先寻址先查TLB然后miss后在查PT,快表命中率很高,因为一个事实:程序最长访问的也没几个。 - 空间优化
多级页表
4、程序内部的内存管理-分段
分段和分页结合的方式:每个段有很多页,页表中存储段号和页号唯一映射物理帧号,物理层面几乎都不支持段页结合只有少数CPU支持,但保留了段的概念。
三、内存相关的系统调用
1、用户态和内核态
- 用户态转为内核态一般是申请外部资源时,外部资源有哪些?
- 系统调用
- 进程 exit fork
- 文件 chmod chown
- 设备 read write
- 信息 getxxx
- 通信 pipe mmap(申请内存 大于128k,零拷贝技术) brk(申请内存 小于128k)
- 中断 缺页中断
- 异常
因为用户无法直接操作硬件,所以需要转为内核态
- 系统调用
四、Java内存
在java中 对象的存储结构 是分为对象头,对象体
对象头
-
Mark Word(64bit 8字节) :记录对象源信息 例如:锁、对象年龄
-
Klass Word (32bit 4字节/8字节):这指向Metaspace(C++中) 中一个 Klass对象(记录对象元数据信息)
- 当开启压缩时,是4字节,默认是开启
- 不开启压缩时,是8字节
- Klass 通过c++中的java_mirror 指向堆中Class对象
-
Array Length (32bit 4字节):数组长度,如果是数据对象会有值
对象体
- 存放局部变量
指针压缩技术
- java的对象是8字节对齐的,所以32bit地址表示2^32*8Byte=32DB的内存地址,所以在堆内存32G以内都是默认开启指针压缩的,每个对象的地址用4字节表示,但是堆超过32G则无法开启压缩,每个对象地址必用8字节表示
学习自B站up主free-coder
https://www.bilibili.com/video/BV1u7411z7Sv/?spm_id_from=333.999.0.0&vd_source=5cd000f583af07505da743bd1280ab0d
https://www.bilibili.com/video/BV1454y1X7rk?p=5&spm_id_from=pageDriver&vd_source=5cd000f583af07505da743bd1280ab0d