JAVA程序员需要了解的计算机底层知识(4)
JAVA程序员需要了解的计算机底层知识(4)
内存的发展历程
在DOS时代,一台计算机只能运行一个进程(一些特殊的算法可以实现多进程)
Windows9.X的时候,多个进程可以装入内存,但是这个时候会引发两个问题
1.进程太多,会导致内存不够用
2.互相打扰,可能一个进程把另外一个进程干掉。
解决进程太多,会导致内存不够用的问题
分页:在双击应用程序,开启进程的时候,并不是把整个进程都load到内存中,而是把进程切碎了分成了一个个页,每个页的大小标准是4K,先把main所在的页加载到内存中,后续用到那个页的数据的时候再把相应的页加载到内存中。如果内存满了怎么办?会触发LRU算法(Least Recently Used 最不常用),把最不常用的页放到swap分区,再需要用到这个页的时候再把它从swap分区拿回来。
LRU算法:
拿数据库来举例:DB去把数据存入缓存,这些数据放在一起像是一个集合,现在的问题是,如何找出里面最不常用的那个数据?
解决方案:
- 创建一个集合,把每个页都赋上时间戳,每次使用的时候修改时间戳,想要找到最不常用的页就找到时间戳最靠前的那个元素就可以了。
面临问题:每次找元素都需要遍历集合,时间空间复杂度为O(n),性能不高。 - 创建一个链表,最先load的页放在集合最开头的位置,第二个load放在第二个位置,第三个放在第三个位置 … 以此类推,用到页如果已经加载过了,就把这个页单独拿出来,使后边元素的指针指向前面的一个元素,自己放到链表最后的位置并且建立新的指针,找到元素后的操作是O(1),这样就保证了最不常用的页永远在集合的最前面。
但是这样又会引发问题:从链表上查找一个元素,依然需要遍历,依然还是和链表的长度成正比,是一个O(n)的操作。 - 第三种方式:使用hsahmap+linklist结合体,java自带的LinkedHashMap可以实现,哈希表(保证 查找操作O(1)) + 链表 (保证 排序操作和新增操作 O(1)))
分页置换算法。LRU算法。所有涉及缓存的算法,都有LRU或者LFU。就是找出最不常用元素的算法。
解决互相打扰,可能一个进程把另外一个进程干掉的问题
互相打扰,相爱相杀?
在以前的DOS WIN31的系统中,多个进程load进内存,是可以互相访问,甚至干掉对方。
为了保证互不影响 -,让进程工作在虚拟空间,程序中用到的空间地址不再是直接的物理地址,而是虚拟的地址,这样,A进程永远不可能访问到B进程的空间。
如上图,P1,P2,P3,P4四个进程都是工作在虚拟空间,每个进程都认为自己独享整个系统)+CPU,内部都有一个虚拟的内核,再加载的时候,会通过内部的虚拟内核映射到真正的OS内核,OS内核又通过MMU运算单元,把自己需要被使用到的页加载到物理内存,如果内存满了就会把最不常用的页加载到swap空间,被加载到物理内存的进程在内核态,而P1-P4如果想访问其他的物理内存,必须经过OS内核和MMU的中转才能找到真正的物理内存。这样就解决了进程之间互不打扰(物理地址的映射是是通过MMU内存管理单元 来管理的,是不允许用户空间来参与的)
扩展ZGC
算法叫做:Colored Pointer
GC信息记录在指针上,不是记录在头部, immediate memory use
42位指针 寻址空间4T JDK13 -> 16T 目前为止最大16T 2^44
颜色指针站4位,这四位存在互斥的关系(只有其中一个可以为1),也就是说不同的标记指向4个空间范围是不一样的虚拟地址,但是又指向同一个物理地址。
CPU如何区分一个立即数 和 一条指令
总线内部分为:数据总线 地址总线 控制总线
地址总线目前:48位
颜色指针本质上包含了地址映射的概念
JAVA程序员需要了解的计算机底层知识(1)
JAVA程序员需要了解的计算机底层知识(2)
JAVA程序员需要了解的计算机底层知识(3)
如果我有理解不对的地方,请请留言指正。
戏入人生 手打。