CPU和内存 程序(线程)关系

简介: 先来介绍下CPU: CPU容量小 需要别人给她指令但是运转速度快 主要是寄存器构成的 1. 通过控制器从内存中读入指令和数据到寄存器中并根据结果来控制整个计算机 2.

先来介绍下CPU:
CPU容量小 需要别人给她指令但是运转速度快 主要是寄存器构成的
1. 通过控制器从内存中读入指令和数据到寄存器中并根据结果来控制整个计算机
2. 而运算器负责运算从内存读入的寄存器的数据
3. 时钟负责发出CPU开始计时的时钟信号
4. 运行速度:CPU>内存>硬盘
5. 只是用来运行指令 但是不能保存指令 指令是在内存中
6. 第一条指令是在内存的最顶端

寄存器有很多类型 可以存指令还有数据

电脑的运行过程

CPU一开始从内存中读入指令 是跳转指令然后去BIOS(系统的自检 检查内存 硬盘显卡之类的有无问题) 从中断向量表获取指令    然后把操作系统从硬盘中唤醒 运输到内存中
**总结:CPU运转很快 但是 得从别人那获取指令才知道做什么** 
比如指向一个斐波那契数列 是操作系统设置好进程 设置好程序计数器然后让CPU开始计算 如果之前的程序抢占了CPU 那CPU就会执行那个程序的指令 而被抢占的则是保存记录 等待继续操作

CPU最重要的是寄存器和程序计数器(用来记住要执行的下一条指令地址)

CPU还有个缓存 如果CPU访问内存一个位置 以后还会多次访问 并且附近的位置也会很快被访问到 这是程序的局部性原理把他们加入到缓存里会快很多 但是操作系统如果做程序切换那么缓存会失效。
CPU还可以进行流水线操作

CPU所在的是一个批处理的计算机系统 意思就是说 内存中有多个任务 而CPU的任务就是运行计算完成这些任务 如果一个任务遇到了IO操作(速度很慢 内存和硬盘都在加载数据) 那么操作系统就让CPU执行下一个任务 
注意:程序在内存中是由地址的动态重定位意思就是 每次运行的时候会记录下每个程序的其实地址 CPU专门有个寄存器来存储初始位置  这样子切换程序的时候不会有数据覆盖
CPU还会增加一个寄存器来记录程序在内存中的长度 这样每次程序访问的时候都会拿地址和这个长度比较判断有没有越界
上述的寄存器和计算内存地址的方法 统称 MMU(内存管理单元)

磁盘缓存就是将硬盘的东西读入内存中 下次访问的时候速度快一点

但是遇到问题 程序很大怎么办?
这个时候根据 局部性原理 把一个程序分成多个小块 按块装在到内存中 叫页框
因为大部分程序都是集中运行在着几个页框中 于是这些页也叫做工作集 这些工作的真实内存映射到对应的物理内存 这个程序其他未加载的部分其实并没有运行 这就涉及到了 虚拟内存是把磁盘作为部分的内存使用 通过分页式或者分段式将正在运行的内容加载到内存中不用的放在磁盘里 这样看起来内存变大了 其实没有
如果真实的内存满了 那么久将现有的页框置换到硬盘上 加载其他的页框进来
每次运行的内存中页框都是要去找对应 物理内存 于是就 将那些最常访问的页框以及对应的物理内存放在缓存中

对于CPU加载程序的时候会分段加载到内存中 对应的也对程序进行标准话 分为代码段 数据段 堆栈段之类的 然后操作系统记住每一段的开始和结束地址 如果一个程序非法访问那么就 杀死它

CPU涉及到函数的调用 : 这个时候可以先介绍一下线程
1. 线程生活在线程池里面
2. 程序可以理解为多个线程的结合体
3. 线程被加载到内存 然后进入CPU 但是需要排队 如果线程赖着CPU不走 就会被垃圾回收掉
4. 每个线程只能在CPU上运行一端时间(或者被其他线程抢占资源打断或者出现IO流这样的耗时操作) 然后再保存自己的信息再等待 等着被唤醒
在就绪和运行中轮转 知道把工作做完
5. 线程有时候需要加锁 如果出现死锁 那么就得kiss掉一个 所以加锁的时候要记住 按照操作系统的算法比较大小 然后从最大的开始加锁
6. 线程是存在线程池中 如果电脑重启那么一切都会置空
7. 线程是被加载到内存中然后开始操作的 过程是 先将class文件加载到方法区中

class的过程:
1. class文件进入方法区等待调用一个线程 线程进来提取了代码指令就开始在工作台进行操作(栈帧)也可以说是一个函数调用 多个工作台组成一个java栈 一个工作台就是一个栈帧依次执行最上的 然后销毁 加入的话也是压在最上面 在工作台里面还有一个局部变量区和操作数栈 最后把操作后的数弹出 这里的操作数算是在操作数栈里面 而不像CPU是放在一个个寄存器里

总结:1. 程序(线程集)被加载到内存中
注意:程序是分段的 意思就是说 程序不是整个都被加载到内存中 而是加载目前需要的个体 也可以理解为线程
2. 从线程从方法区中的class调用指令 然后逐个执行里面线程中的函数调用(栈帧)
执行的过程是CPU来操作的 CPU从内存中读取指令和数据到寄存器 然后根据结果操作整个计算机
3. 线程在栈帧操作的时候会创建栈区 临时保存变量 结束后删除 如果是new的话就会在堆中创建长期的对象 如果不用了就垃圾回收系统自动回收对象。
4. 线程也可被中断 因为CPU去执行其他线程了
5. 函数的调用 CPU执行线程中的指令的时候 逐行往下执行 遇到函数调用就 根据目标函数的地址进入改函数继续执行 最后到结尾 返回函数调用的结果和执行指令(跳转到调用初始的位置的下一行) 回到函数调用的位置执行下一行

额外涉及补充:

  • 通过DLL实现函数共有 节约内存

  • 哈夫曼编码大幅提升压缩比率

  • 运行环境是操作系统+硬件

  • windows克服了应用在不同cpu的差异

源代码如何运行

编译器可以通过freeBSD的ports机制生成合适的本地代码但是本地文件( obj文件)无法直接运行 需要链接成可执行的exe文件 需要导入库和   直接和exe文件结合的静态链接库 可执行文件的运行条件是需要  再配置信息

堆栈方法区

程序加载的时候还会创建堆和栈: 简单讲一下堆栈方法区

数据都保存在栈中 操作的时候把数据一个一个加入那个桶 得出计算结果然后返回
2. 堆的话是 如果new一个对象出来 对象就在堆里面 内部有个计数器 如果没有标志使用就是废弃的对象会被垃圾回收 干掉

目录
相关文章
|
1月前
线程CPU异常定位分析
【10月更文挑战第3天】 开发过程中会出现一些CPU异常升高的问题,想要定位到具体的位置就需要一系列的分析,记录一些分析手段。
61 0
|
22天前
|
NoSQL 测试技术
内存程序崩溃
【10月更文挑战第13天】
118 62
|
27天前
|
Java 开发者
如何通过易语言多线程提升程序响应速度
如何通过易语言多线程提升程序响应速度
131 62
|
7天前
|
弹性计算 Kubernetes Perl
k8s 设置pod 的cpu 和内存
在 Kubernetes (k8s) 中,设置 Pod 的 CPU 和内存资源限制和请求是非常重要的,因为这有助于确保集群资源的合理分配和有效利用。你可以通过定义 Pod 的 `resources` 字段来设置这些限制。 以下是一个示例 YAML 文件,展示了如何为一个 Pod 设置 CPU 和内存资源请求(requests)和限制(limits): ```yaml apiVersion: v1 kind: Pod metadata: name: example-pod spec: containers: - name: example-container image:
|
10天前
|
存储 缓存 Java
结构体和类在内存管理方面的差异对程序性能有何影响?
【10月更文挑战第30天】结构体和类在内存管理方面的差异对程序性能有着重要的影响。在实际编程中,需要根据具体的应用场景和性能要求,合理地选择使用结构体或类,以优化程序的性能和内存使用效率。
|
19天前
|
监控 Java 数据库连接
线程池在高并发下如何防止内存泄漏?
线程池在高并发下如何防止内存泄漏?
|
15天前
|
存储 关系型数据库 MySQL
查询服务器CPU、内存、磁盘、网络IO、队列、数据库占用空间等等信息
查询服务器CPU、内存、磁盘、网络IO、队列、数据库占用空间等等信息
187 1
|
20天前
|
Java 开发者
如何通过易语言多线程提升程序响应速度?
如何通过易语言多线程提升程序响应速度?
|
1月前
|
存储 程序员 编译器
简述 C、C++程序编译的内存分配情况
在C和C++程序编译过程中,内存被划分为几个区域进行分配:代码区存储常量和执行指令;全局/静态变量区存放全局变量及静态变量;栈区管理函数参数、局部变量等;堆区则用于动态分配内存,由程序员控制释放,共同支撑着程序运行时的数据存储与处理需求。
99 21
|
21天前
|
监控 Java 数据库连接
使用线程池时,如何避免内存泄漏的问题?
使用线程池时,如何避免内存泄漏的问题?