| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 系统运维 -> 从零开始第一期——所有JAVA后端程序员必须充电!!!!深入理解Linux内存管理 -> 正文阅读 |
|
[系统运维]从零开始第一期——所有JAVA后端程序员必须充电!!!!深入理解Linux内存管理 |
Java之所以被程序员们吐槽为入门门槛低,就是因为JVM垃圾回收器帮助管理了JVM内存。但也有一句话,天下没有免费的午餐,吃的时候有多豪横,吃完就有多难受。你真觉得你不用管理内存?那你是想多了,作为后端程序员,JVM你得管,linux你得管,没有一样能跑的掉。 今天我们就从linux源码上走一走linux内存管理。 当然本来我是想把这期做在《细读经典》系列里去过一遍《深入理解linux虚拟内存管理》,但是限于个人精力(还有之前托更了好多东西)先做一个简化版,当然也不算简化版,算是一个比较深入的阐述吧。 前戏在开始内存之前,我可能要说一些其他东西。 1、进程间通信(1)管道:进程通过共享管道实现进程通信,实际上就是在物理内存空间内开辟出一段缓存空间。分有名管道和无名管道 无名管道,需要以文件的方式进行操作(读写),而操作文件,就需要文件描述符(fd)进行读写,文件描述符通过调用pipe方法得到(非open方法,一般而言通过调用open方法打开文件获取文件描述符),因为它没有文件名,就无法用open方法得到文件描述符,也正是因为它是一个没有名称的管道文件,所以叫无名管道,且只用于亲缘进程之间的通信(因为没有文件描述符,只能通过亲缘关系传递管道的文件描述符,例如通过fork子进程)。当然,这里的亲缘进程,可以是子进程,孙进程,孙子进程,子子孙孙无穷匮也。 无名管道API
有名管道,当然就是有文件名,可以用open函数打开文件,然后用该文件描述符进行管道建立并进行通信。所以很明显,有名管道既可以用于亲缘进程之间的通信,也可以用于非亲缘进程之间的通信。 有名管道API
管道还牵扯到单向通信和双向通信,我就不展开了,现在还用不到 (2)System V IPC(System linux V(罗马字字母)版本的Inter-Process Communication,?人话就是linux第五版本进程间通信) 管道是一种很原始的进程通信方式,早在linux设计之初就存在管道。随着linux版本升级到第五版本,提供了新的进程间通信方式,包含消息队列,信号量和共享内存 消息队列:看API比看文字清晰,msqid作为消息队列标识符,利用msgsnd发送,利用msgrcv接受消息,利用msgctl操作消息队列上的内容,提供删除操作。调用过程就不展开了 消息队列API
共享内存:还是在物理内存上开辟一段缓存空间,不过与管道不同的是,使用共享内存是通过直接使用地址来共享读写的,而不需要经过系统调用。 共享内存API
信号量:java信号量同理,所以比较重要,进程和线程的信号量是对所操作资源的保护。 这里当然要先说以下同步和互斥的关系,互斥是指资源访问的排他性,和访问顺序无关,同步是在互斥的基础上,实现有序访问。 信号量就是指定同一时间能够访问临界区资源的进程的数量。 信号量API看似简单,其实还是很精妙的,在JAVA里,信号量底层是AQS,AQS底层又是一些unsafe类,我之前也有文章讲unsafe类的,传送门:好文笔记——unsafe类_u014783007的博客-CSDN博客
2、用户态和内核态我们之前一直在说系统调用,包括刚刚在说进程通信时也放了一大堆API,那么系统调用到底是什么呢? 一般而言,程序要不运行在用户态(用户交互),要不运行在内核态(系统调用)。 用户态切换到内核态是在程序申请外部资源(内存条,网卡,声卡,usb等等等等)时进行切换。一般而言,当程序在进行系统调用,或产生中断,或产生异常时就会从用户态向内核态进行切换。 例如读一个文件,我们会调用open创建fd,再用fd去进行write或read的API系统调用。例如我们分配内存时调用malloc,就会调用系统函数brk或mmap进行系统调用;又例如我们常听的缺页中断等等,程序中存在大量的系统调用(当然你映射到JAVA,new对象也是系统调用)。 系统调用,再linux中输入:
会显示所有的系统调用,这块就留个大家自己开发了。 这里我再举个例子,以多路复用IO为例,select和poll在进行系统调用的时候,需要把所有的fd从用户态拷贝到内核态进行遍历,本次调用结束之后,再把fd拷贝回来,而epoll则只需要在第一次进行系统调用的时候拷贝一次所有的fd,之后将用户关系的文件描述符的事件存放到内核的一个事件表中,这样只需要增量维护事件表,从而提升性能。当然epoll还会牵扯到mmap,红黑树(事件链表),等等,还会牵扯到LT,ET效率问题(LT:水平触发,效率会低于ET触发,尤其在大并发,大流量的情况下。但是LT对代码编写要求比较低,不容易出现问题。LT模式服务编写上的表现是:只要有数据没有被获取,内核就不断通知你,因此不用担心事件丢失的情况。?ET:边缘触发,效率非常高,在并发,大流量的情况下,会比LT少很多epoll的系统调用,因此效率高。但是对编程要求高,需要细致的处理每个请求,否则容易发生丢失事件的情况。从本质上讲:与LT相比,ET模型是通过减少系统调用来达到提高并行效率的)。你会发现其实系统函数是一个很有趣的部分,也是更贴近我们理论上所学习的各个模型的。 中断和异常不展开,有兴趣的同学自行脑补。 3、计算机组成原理(简化版) //TODO 正戏1、基本概念 2、实现过程 3、底层源码 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/15 20:34:53- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |