- 博客(39)
- 收藏
- 关注
原创 JAVA刷题练习
JAVA学习最大子数组和给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。子数组 是数组中的一个连续部分。示例 1:输入:nums = [-2,1,-3,4,-1,2,1,-5,4]输出:6解释:连续子数组 [4,-1,2,1] 的和最大,为 6 。示例 2:输入:nums = [1]输出:1示例 3:输入:nums = [5,4,-1,7,8]输出:23需要一个变量pre保存连续子数组的和,每次加后面的值的时候都要
2022-04-18 17:48:37
498
原创 KVM内存气球技术
KVM内存气球技术通常来说,要改变客户机占用的宿主机内存,是要先关闭客户机,修改启动时的内存配置,然后重启客户机才能实现。而内存的ballooning(气球)技术可以在客户机运行时动态地调整它所占用的宿主机内存资源,而不需要关闭客户机。Ballooning技术形象地在客户机占用的内存中引入气球(Balloon)的概念,气球中的内存是可以供宿主机使用的(但不能被客户机访问或使用),所以,当宿主机内存使用紧张,空余内存不多时,可以请求客户机回收利用已分配给客户机的部分内存,客户机就会释放其空闲的内存,此时若
2022-01-10 11:03:43
3538
1
原创 启动中的内存初始化
要观察启动过程中的内存初始化当然要从初始化系统函数start_kernel开始(V4.7),由于start_kernel代码篇幅过多,这里只摘取有关于内存的部分。asmlinkage __visible void __init start_kernel(void){ page_address_init(); setup_arch(&command_line); mm_init_cpumask(&init_mm); setup_per_cpu_areas(); build_al
2021-11-15 15:51:04
1393
原创 内存池(memory pool)
前言通常的进程发起申请内存的动作之后,会在系统的空闲内存区寻找合适大小的内存块(底层分配函数__alloc_node_mask),如果满足就直接分配,如果不满足就会向上查找。如果过大就会进行分裂,一部分分给申请进程,一部分放入空闲区。释放时需要找到这个块对应的伙伴,如果伙伴也为空闲,就进行合并,放入高阶空闲链表,如果不空闲就放入对应链表。同时对于多线程申请和释放内存,需要加锁。这样的默认的分配方式考虑到了系统中的大部分情况,具有通用性,但是无可避免的会产生内部碎片,而且加锁,解锁的开销也很大。如果可以对
2021-11-15 15:49:48
9070
原创 linux中的伙伴算法
伙伴系统1.前言Linux内核内存管理的一项重要工作就是如何在频繁申请释放内存的情况下,避免碎片的产生。Linux采用伙伴系统解决外部碎片的问题,采用slab解决内部碎片的问题,在这里我们先讨论外部碎片问题。避免外部碎片的方法有两种:一种是之前介绍过的利用非连续内存的分配;另外一种则是用一种有效的方法来监视内存,保证在内核只要申请一小块内存的情况下,不会从大块的连续空闲内存中截取一段过来,从而保证了大块内存的连续性和完整性。显然,前者不能成为解决问题的普遍方法,一来用来映射非连续内存线性地址空间有限,二
2021-07-25 16:16:53
474
原创 NUMA架构下的内存分配策略
NUMA下的内存分配策略通常的内存分配策略我们已经有所了解了。UMA是统一内存访问,无论任何 CPU 执行操作,访问时间都相等。而NUMA是非统一内存访问,在不同的节点的访问速度不一样,离本地越远访问越慢。在NUMA上我们有不只一个节点,我们可以在不同的节点上分配内存。内存分配和策略通常NUMA下的内存分配有显式和隐式两种。显式分配显式分配即指定节点的分配函数,此类基础分配函数主要有2个:Buddy系统的 alloc_pages_node()和SLAB系统的kmem_cache_alloc_nod
2021-07-20 19:53:33
2759
原创 内存快速分配和慢速分配
内存快速分配和慢速分配内存页面的分配最终都交由伙伴系统的页面分配器。页面分配的函数在内核有各种各样的实现,但最终都会调用一个共同的接口::__alloc_pages_nodemask()常见的页面分配的API__alloc_pages_node /*返回struct page的指针*/ __alloc_pages __alloc_pages_nodemaskalloc_pages /*返回struct page的指针*/ alloc_pages_curr
2021-07-20 19:52:21
1083
原创 内核同页合并KSM
KSM(Kernel Samepage Merging)共享内存的概念在现代操作系统中很常用了,比如,一个程序启动时会与父进程共用它的全部内存。当其中一个进程发生变化时,就会触发写时复制,把原来的内容写入到新的内存页中,再进行修改。这时其他的未改动的页面仍然是共享的。在执行完exec之后所有的页面不再共享,父子进程各有各的物理页。共享内存是进程间通信的一种手段,多个进程的地址空间共享同一块物理内存,共享内存的进程在进行修改之后同样也会修改物理内存。当linux启用了KSM之后,KSM会检查多个运行中的
2021-07-20 19:51:25
1088
原创 cgroup之内存子系统的使用
memory cgroupCgroup的memory子系统,即memory cgroup(memcg),提供了对系统中一组进程的内存行为的管理,从而对整个系统中对内存有不用需求的进程或应用程序区分管理,实现更有效的资源利用和隔离。在实际业务场景中,为了防止一些应用程序对资源的滥用(可能因为应用本身的bug,如内存泄露),导致对同一主机上其他应用造成影响,我们往往希望可以控制应用程序的内存使用量,这是memcg提供的主要功能之一,当然它还可以做的更多。Memcg的应用场景,往往来自一些虚拟化的业务需求,
2021-07-15 10:47:04
4659
原创 CGroup的原理和使用
CGroupLinux CGroup全称Linux Control Group, 是Linux内核的一个功能,用来限制,控制与分离一个进程组群的资源(如CPU、内存、磁盘输入输出等)。这个项目最早是由Google的工程师在2006年发起(主要是Paul Menage和Rohit Seth),最早的名称为进程容器(process containers)。在2007年时,因为在Linux内核中,容器(container)这个名词太过广泛,为避免混乱,被重命名为cgroup,并且被合并到2.6.24版的内核
2021-07-14 17:14:11
7838
原创 hugetlbfs的使用测试
hugetlbfsCPU缓存中有一组缓存专门用于缓存TLB,但其大小是有限的。当采用的默认页面大小为 4KB,其产生的TLB较大,因而将会产生较多 TLB Miss 和缺页中断,从而大大影响应用程序的性能。操作系统以 2MB 甚至更大作为分页的单位时,将会大大减少 TLB Miss 和缺页中断的数量,显著提高应用程序的性能。这也正是 Linux 内核引入大页面支持的直接原因。好处是很明显的,假设应用程序需要 2MB 的内存,如果操作系统以 4KB 作为分页的单位,则需要 512 个页面,进而在 TL
2021-06-11 17:44:43
3511
1
原创 巨页的配置和修改
巨页背景知识Linux中把页面作为管理内存的基本单位,一个页面为4KB。如果一个程序在运行过程中会用到很多的内存,那么必然会导致很多的TLB未命中和缺页异常的情况,因为一个页最大只能是4KB所以也就造成了这种问题的发生。如果直接修改默认的页面大小,那么又容易造成内存浪费,显然是不可取的。Linux引入了巨页(Huge page)的概念。允许一个页面的大小超过4KB,默认为2MB。说到这里其实你也应该知道为什么默认为2MB了。 Linux的采取4级页表管理虚拟地址到物理地址的转换,32位系统中页表项占4
2021-06-11 17:43:23
3815
原创 管道通信和go中的channel
管道通信用户态的进程之间需要同步和交换数据,本质上是需要依靠内核来实现的。Unix系统提供了几种不同的进程间通信的方式来供程序员使用,这里只讨论管道通信。管道通信适合在进程间实现生产者消费者的交互。有些进程向管道中写入数据,而另外的一些进程则需要从管道中读取数据。这是对管道通信的大致理解。管道管道是进程之间的一个单向数据流,即一个进程写入管道的所有数据都由内核定向到另一个进程,另一个进程就可以从管道中读取到数据。在shell命令中可以使用“|”操作符来创建管道,使用下面的语句用shell来创建两个
2021-05-24 11:12:18
472
原创 OOM Killer机制
oom killer概念oom killer是内核设计的一种机制,在内存不足时选择一个占用内存较大的进程把他杀死,释放这一部分内存来满足内存请求的的需求。oom(out of memory)OOM(Out of Memory)指Linux在无可用内存时的一个最后策略。当系统中可用内存过少时,OOM killer会选择kill某些进程,来释放这些进程所占用的内存。void out_of_memory(int gfp_mask){ struct mm_struct *mm = NULL; tas
2021-05-24 11:10:42
4112
原创 内存平衡
内存平衡gfp_mask是内存分配掩码,gfp是get free page的缩写GFP分配掩码的布局分配掩码包括两部分,内存域修饰符(占低4位)和内存分配标志(从第5位开始)1.内存域修饰符内存域zone有ZONE_DMA、ZONE_DMA32、ZONE_NORMAL、ZONE_HIGHMEM、ZONE_MOVABLE,内存域的修饰符有:#define __GFP_DMA 0x01u#define __GFP_HIGHMEM 0x02u#define __GFP_DMA
2021-04-27 18:21:42
278
原创 mm和active_mm
mm和active_mm1.简介进程描述符task_struct中有这样的字段active_mm和mm,他们跟进程的地址空间相关。struct task_struct { ... struct mm_struct *mm, *active_mm;...};对于普通的用户进程来说mm字段指向他的虚拟地址空间的用户空间部分,对于内核线程来说这部分为NULL。2.那么active_mm是指什么呢?我们有“真实地址空间”和“匿名地址空间”。两者的的区别在于匿名地址空间不关心用户级的页表,
2021-04-27 18:20:57
1839
原创 pdflush内核线程
pdflush内核线程早期版本的Linux使用bdflush内核线程系统地扫描页高速缓存以搜索要刷新的脏页,并且使用另一个内核线程kupdate来保证所有的页不会“脏”太长的时间。Linux 2.6用一组通用内核线程pdflush代替上述两个线程。这些内核线程结构灵活,它们作用于两个参数:一个指向线程要执行的函数的指针和一 个函数要用的参数。系统中pdflush内核线程的数量是要动态调整的: pdflush 线程太少时就创建,太多时就杀死。因为这些内核线程所执行的函数可以阻塞,所以创建多个而不是一个pd
2021-04-13 17:48:58
384
原创 go中的sync包
go中的sync包在Go语言中,除了使用channel进行goroutine之间的通信和同步操作外,还可以使用syne包下的并发工具。并发工具类说明Mutex互斥锁RWMutex读写锁WaitGroup并发等待组Map并发安全字典Cond同步等待条件Once只执行一次Pool临时对象池Mutex(互斥锁)sync. Muer互斥锁能够保证在同一个时间段内仅有一个goroutine持有锁,这就能够保证在某一时间段内有且仅有一个g
2021-04-13 17:46:59
960
原创 内存紧缺回收情况分析
内存紧缺回收页分配时内存紧缺__alloc_pages()函数无法在给定的内存管理区(memory zone)中分配一组连续页框。alloc_pages用于分配2的order次方个连续的页框。它返回第一个所分配页描述符的地址,如果分配失败返回null。#define alloc_pages(gfp_mask, order) \ alloc_pages_node(numa_node_id(), gfp_mask, order)alloc_pages_nodestatic inline st
2021-04-07 09:55:47
284
原创 GO操作influxdb
influxDBinfluxDB名词database:数据库;measurement:数据库中的表;points:表里面的一行数据。还有一个重要的名词: series所有在数据库中的数据,都需要通过图表来表示,series表示这个表里面的所有的数据可以在图标上画成几条线(注:线条的个数由tags排列组合计算出来)对influxdb的操作:#创建数据库create database "db_name"#显示所有的数据库show databases#删除数据库drop data
2021-03-22 16:12:59
5117
原创 GORM教程
GORMgorm是一个使用Go语言编写的ORM框架。它文档齐全,对开发者友好,支持主流数据库。安装go get -u gorm.io/gorm连接数据库引入驱动import "gorm.io/driver/mysql"import "gorm.io/driver/postgres"import "gorm.io/driver/sqlite"import "gorm.io/driver/mssql"可以根据自己的需要选择对应的包连接数据库(mysql)import ( "gorm
2021-03-16 17:34:24
3117
原创 页框回收算法(PFRA)——2
页框回收中的反向映射PFRA的目的之一就是能释放共享页框,为了达到这个目的Linux2.6内核能够快速定位指向同一页框的所有页表项,这个过程就叫做反向映射。反向映射简单来说就是在页描述符中加入附加字段,这样就把某个页描述符它所确定的页框对应的全部页表项联接起来,但是这样的话一旦对该链表更新会有很大的开销。所有就有一种成熟的技术出现,Linux2.6就有叫做面向对象的反向映射的技术。实际上对于任何可以回收的用户态页面,内核保留系统中该页所在所有线性区(对象)的反向链接,每个线性区描述符存放一个指针指向一个
2021-03-09 20:48:18
491
原创 页框回收算法(PFRA)——1
页框回收算法(PFRA)通过请求调页机制,只要用户态进程继续执行,他们就能获得页框,然而,请求调页没有办法强制进程释放不再使用的页框。因此,迟早所有空闲内存将被分配给进程和高速缓存。linux内核的页框回收算法采取从用户态进程和内核高速缓存“窃取”页框的办法补充伙伴系统的空闲块列表。页框回收算法的目标之一就是保存最少的空闲页框池以便内核可以安全地从“内存紧缺”的情形中恢复过来。选择目标页页框回收算法(PFRA)的目标就是获得页框并使之空闲。PFRA按照页框所含内容,以不同的方式处理页框。我们将他们区分
2021-03-01 17:55:19
575
原创 Linux——中断下半部(深入代码理解)
中断下半部分中断分为上半部和下半部分,操作系统把一些紧急的任务,需要硬件参与的任务放在上半部去完成。而把一些不是很急切需要完成的任务放在下半部分来执行。中断下半部的三种机制Softirq(软中断)软中断是一组静态定义的下半部接口,可以在所有处理器上同时执行(即使两个类型相同也可以)。软中断的结构体struct softirq_action { void (*action)(struct softirq_action*); };softirq_action这个数组有32项,每个被注册的
2021-02-05 22:17:19
763
原创 内存水位watermark
watermarkstruct zone { /* Read-mostly fields *//* zone watermarks, access with *_wmark_pages(zone) macros */unsigned long watermark[NR_WMARK];long lowmem_reserve[MAX_NR_ZONES];...}每个内存管理区都有一个数组watermark,内核中定义了三个watermark来表示当前系统剩余的空闲内存。high当剩余
2021-02-01 19:14:23
3150
原创 Linux内存管理相关的一些知识(请求调页)
内存管理如果物理内存是分布式的,由多个cell组成(比如每个核有自己的本地内存),那么CPU在访问靠近它的本地内存的时候就比较快,访问其他CPU的内存或者全局内存的时候就比较慢,这种体系结构被称为Non-Uniform Memory Access(NUMA)。以上是硬件层面上的NUMA,而作为软件层面的Linux,则对NUMA的概念进行了抽象。即便硬件上是一整块连续内存的UMA,Linux也可将其划分为若干的node。同样,即便硬件上是物理内存不连续的NUMA,Linux也可将其视作UMA。在NUMA
2021-01-25 17:47:54
281
原创 Linux内存映射mmap相关内核代码分析
mmapmalloc的两种情况再用malloc分配内存的时候有两种情况:一种是小于128k的时候调用brk系统调用brk是将数据段(.data)的最高地址指针_edata往高地址推(只分配虚拟空间,不对应物理内存(因此没有初始化),第一次读/写数据时,引起内核缺页中断,内核才分配对应的物理内存,然后虚拟地址空间建立映射关系),如下图:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ay5OhIcw-1610196484204)(https://i.loli.net/2
2021-01-25 17:45:51
420
原创 Linux操作系统之中断上半部
中断上半部中断的概念中断通常被定义为一个事件,这个事件改变处理器执行的指令顺序。中断通常分为同步和异步:同步中断是指当指令执行时由cpu控制单元产生的,之所以称为同步是应为它在一条指令终止执行后之后cpu才发出中断。异步中断是由其他硬件设备依照cpu时钟信号随机产生的。intel手册将同步中断称为异常,异步中断称为中断。中断是由间隔定时器和I/O设备产生的,比如我们的键盘输入。另一方面来说异常是由程序错误产生的,比如除以0,或者内核必须处理的异常(缺页异常)。中断的作用中断提供了一种特
2021-01-25 17:43:59
466
原创 Linux自己编写一个字符设备驱动的实例(+代码)
字符设备驱动Linux字符设备提供连续的数据流,应用程序可以顺序读取,通常不支持随机存取。相反,此类设备支持按字节/字符来读写设备。举例来说,键盘,串口,调制解调器都是典型的字符设备。设备分类linux系统将设备分为3类:字符设备、块设备、网络设备。字符设备:是指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后数据。字符设备是面向流的设备,常见的字符设备有鼠标、键盘、串口、控制台和LED设备等。块设备:是指可以从设备的任意位置读取一定长度数据的设备。块设备包
2020-12-07 16:33:53
775
原创 理解块设备驱动、通用块层、IO调度层的关系和试验
编写块设备1.用户进程与块设备的联系从我们打开文件开始即存在一个file结构体struct file { ... struct address_space *f_mapping; ...};file结构体中内嵌文件地址空间对象结构体address_spacestruct address_space { struct inode *host; /* owner: inode, block_device */ ...} __attribute__((aligned(sizeof(l
2020-12-07 16:32:53
904
1
原创 linux中的open代码分析
sys_open()代码分析open应用程序在操作任何一个文件之前,必须先调用open()来打开该文件,即通知内核新建一个代表该文件的结构,并且返回该文件的描述符(一个整数),该描述符在进程内唯一。open()的格式如下:int open(const char * pathname,int oflag, mode_t mode )pathname:代表需要打开的文件的文件名;oflag:表示打开的标识;O_ACCMODE<0003>: 读写文件操作时,用于取出flag的低2位。O
2020-11-23 11:32:40
400
原创 虚拟文件系统相关的数据结构和操作
虚拟文件系统虚拟文件系统所隐含的思想是把表示很多不同种类文件系统的共同信息放入内核;其中有一个字段或函数来支持Linux所支持的所有实际文件系统所提供的任何操作。对所调用的每个读、写或其他函数,内核都能把它们替换成支持本地Linux文件系统、NTFS文件系统,或者文件所在的任何其他文件系统的实际函数。虚拟文件系统(VFS)的作用虚拟文件系统(Virtual Filesystem)也可以称之为虚拟文件系统转换(Virtual Filesystem Switch,VFS),是一个内核软件层,用来处理与Un
2020-11-23 11:31:35
150
原创 linux中vfs系统调用的实现
vfs系统调用的实现前言用户发出了一条shell命令:把/floppy/TEST 中的MS-DOS 文件拷贝到/tmp/test中的Ext2 文件中。命令shell 调用一个外部程序(如cp),我们假定cp执行下列代码片段:inf = open("/floppy/TEST", O_RDONLY,0);outf = open("/tmp/test", O_WRONLY |O_CREAT |O_TRUNC,0600);do {len = read(inf, buf, 4096);write(out
2020-11-23 11:29:17
856
1
原创 Linux内存检测工具memeleak
memleak功能memleak是一个BCC工具,它跟踪内存分配和空闲事件以及分配堆栈跟踪,随着时间的推移可以显示长期幸存者:那些没有被释放的分配。示例例如,在bash shell进程中运行memleakmemleak -p 3126Attaching to pid 3228, Ctrl+C to quit.[09:14:15] Top 10 stacks with outstanding allocations:[...] 960 bytes in 1 allocatio
2020-11-23 11:28:22
5146
原创 kmalloc和kfree
kmalloc和kfreekmallocstatic __always_inline void *kmalloc(size_t size, gfp_t flags){ if (__builtin_constant_p(size)) { if (size > KMALLOC_MAX_CACHE_SIZE) return kmalloc_large(size, flags);#ifndef CONFIG_SLOB if (!(flags & GFP_DMA)) { i
2020-10-13 09:27:04
4032
原创 Linux中页的一些知识
页页内核把物理页作为内存管理的基本单位。大多数32位体系结构支持4KB的页,64位体系结构支持8KB的页。内核用struct page结构来表示系统中的每个物理页。struct page { unsigned long flags; atomic_t _count; atomic_t _mapcount; struct address_space *mapping; pgoff_t index; unsigned long private; s
2020-10-06 16:27:28
697
原创 Linux中伙伴算法的源码分析
伙伴系统1.前言Linux内核内存管理的一项重要工作就是如何在频繁申请释放内存的情况下,避免碎片的产生。Linux采用伙伴系统解决外部碎片的问题,采用slab解决内部碎片的问题,在这里我们先讨论外部碎片问题。避免外部碎片的方法有两种:一种是之前介绍过的利用非连续内存的分配;另外一种则是用一种有效的方法来监视内存,保证在内核只要申请一小块内存的情况下,不会从大块的连续空闲内存中截取一段过来,从而保证了大块内存的连续性和完整性。显然,前者不能成为解决问题的普遍方法,一来用来映射非连续内存线性地址空间有限,二
2020-08-28 16:58:34
518
原创 虚拟文件系统的数据结构
虚拟文件系统虚拟文件系统所隐含的思想是把表示很多不同种类文件系统的共同信息放入内核;其中有一个字段或函数来支持Linux所支持的所有实际文件系统所提供的任何操作。对所调用的每个读、写或其他函数,内核都能把它们替换成支持本地Linux文件系统、NTFS文件系统,或者文件所在的任何其他文件系统的实际函数。虚拟文件系统(VFS)的作用虚拟文件系统(Virtual Filesystem)也可以称之为虚拟文件系统转换(Virtual Filesystem Switch,VFS),是一个内核软件层,用来处理与Un
2020-08-24 19:21:19
448
原创 Linux进程调度0.11源码
小白对Linux进程调度0.11源码的解析//linux0.11/kernel/sched.cvoid schedule(void)//调度函数{ int i,next,c;//i表示当前进程数组下标,next表示下次切换的进程,c表示当前最大的时间片大小。 struct task_struct ** p;//p是一个指向task_struct指针的指针 /* check alarm, wake up any interruptible tasks that have got a signal
2020-06-10 12:10:07
301
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人