概述
计算机体系原理
CPU + 寄存器 + 内存 + 汇编指令
冯诺依曼结构
程序的装载与执行
进程
物理地址 vs 虚拟地址空间
每个程序「进程」都有自己独立的虚拟地址空间 => 和其他程序互不干扰 + 可以方便的放在物理内存的任何区域
动态链接库 vs 静态链接库
动态链接库
- 节省空间
- 可能在当前计算机中找不到相关的动态链接库
- 与当前计算机不兼容
程序的分时复用 & 调度
CPU >> memory >> IO
- CPU => 3GHz => 0.3ns
- memory => 寻址时间 => 1微秒
- IO => 1ms => 网络 IO => 100ms
时间片 vs 时间片轮转
CPU 用很快的速度轮流做不同的事情
每个程序轮流占用 CPU 的时间片(进程 | 线程)
进程的调度是操作系统的工作,操作系统会根据不同的优先级去调度执行某一个进程
进程 | 线程 何时让出 CPU
- 程序的时间片到了
- 请求慢速设备 => 当慢速设备结束了相关的工作之后,会向 CPU 发起一个中断,中断是 CPU 标准的处理慢速设备的一种应用,中断信号会发送到中断处理程序,此时 CPU 放下手头上的工作,去处理中断处理程序所要求的工作
- CPU 需要响应中断
上下文
上下文:程序运行的环境 => 寄存器 & PC
程序计数器 => PC => Program Counter
放弃 CPU,保存上下文 => 保存到 Memory
拥有 CPU,恢复上下文 => 从 Memory 中恢复
每个 CPU 只有一个 PC
频繁切换上下文会造成很大的资源浪费 => 一次上下文切换需要 10^4 CPU Cycle => 用户态线程【协程】 => 一直拥有 CPU,但是在当前程序中仍然能够实现很多个执行流,并行的去执行不同的事情 => 可以有效的避免 CPU 时钟周期的浪费
进程 & 线程及其占用内存 => 需要自己写调度算法 => 编程语言层面的概念
线程是非常昂贵的 => 上下文切换非常浪费性能 + 很占内存
一个 Java 的线程拥有整个一套方法栈,方法栈大概需要占用 1M(线程所占的方法栈的空间) 左右的空间(1G 的内存,只能开 1024 个线程,此处只代表了线程的方法栈,还有堆)
协程空间 4kb
操作系统
- 对上层提供统一的 API,简化应用开发逻辑 => 通过 Windows 的
CreateProcessA
方法创建新的进程 + 通过 Unix 的 fork 系统调用创建新的进程 - 对下层通过硬件驱动提供兼容性 => 驱动 Driver
进程 vs 线程
在进程内部开启另一个进程A,进程A 就是线程
在 Java 的世界中,进程和线程可以独立的被调度
相同点
- 都拥有独立的 PC,可以独立的执行程序
- 在 Linux 上甚至用同一种数据结构处理线程和进程 => Task => Linux 线程 === 轻量级进程
不同点
- 进程:拥有独立的内存地址空间、文件等资源
- 线程:和其他线程共享内存地址空间、文件等资源
文件系统 & IO
硬盘 => HDD => SSD
文件的本质就是文件流
文件 & 文件指针
磁盘块 => 4096 Byte
文件读取太慢了 => 缓存 & 缓冲区 Buffer => 缓冲区一次性读取一个磁盘块大小 => 缓冲区发送一个中断给 CPU => 可以保证在很慢的速度和内存中去折中 => java.io.BufferedReader
源代码 & AST
AST => Abstract Syntax Tree => 抽象语法树 => 树里面每一个节点代表了源代码中的一个内容 => 有了结构化的内容,就可以分析这棵树
高级语言 到 机器码的过程 => 编译 => compiler
编译过程
源代码 => 解析一个一个关键字 => 关键字 === token => 通过一定的语法规则 => AST => 提取相关信息 => 字节码(平台相关的目标代码)
AST === 中间表示 => 同样一颗 AST🌲可以根据不同的平台变成多个平台的代码 => 源代码 到 AST 可以使用同一份代码 => 编译器前端:从源代码到 AST 的过程 => 编译器前端这个过程可以复用
编译器后端:从 AST 到目标代码的过程
知识点
- 一个程序为什么不能跨平台
不同的 CPU 有着不同的架构,目前最广泛的桌面计算机的架构 x86(指令集:告知 CPU 每条指令的作用),不同的 CPU 使用相同的指令集可以运行相同的程序(eg. Inter & AMD都使用 x86 指令集) - windows vs Linux 两者指令集都是 x86,两者程序不能通用
- 程序中会调用一些操作系统相关的东西,二者操作系统不同,windows 上有的东西 Linux 没有,eg.
createProcess
创建进程,并且 windows 带有图形化界面,Linux 没有 - 程序会创建进程,进程跑在内存中,程序的进程在内存的布局不同,Linux 不能理解 .exe 程序的进程在其内存的布局
- 《程序员的自我修养》
- Linux 中没有线程的概念
- MacOS vs UNIX vs Linux vs POSIX ==> UNIX
POSIX => 定义了一组接口 - 硬件之上抽象出操作系统,操作系统使用驱动这个抽象和不同的外设打交道,为了不同的操作系统使用同一套代码,抽象出JVM
抽象优点:统一方便
抽象缺点:效率低
如果非常依赖效率,直接操作当前硬件的东西,例如 C | 汇编,业务系统,实现业务逻辑,使用高级语言,不关心底层细节
网友评论