本文基于OpenJDK17进行讨论 在JDKNIO针对堆外内存的分配场景中,我们经常会看到System.gc的身影,比如当我们通过FileChannelmap对文件进行内存映射的时候,如果JVM进程虚拟内存空间中的虚拟内存不足,JVM在native层就会抛出OutOfMemoryError。 当JDK捕获到OutOfMemoryError异常的时候,就会意识到此时进程虚拟内存空间中的虚拟内存已经不足了,无法支持本次内存映射,于是就会调用System.gc强制触发一次GC,试图释放一些虚拟内存出来,然后再次尝试来mmap一把,如果进程地址空间中的虚拟内存还是不足,则抛出IOException...

  QrTANuPTD5bh   2024年04月01日   34   0   0 Java

本文基于Linux内核5.4版本进行讨论 自上篇文章《从Linux内核角度探秘JDKMappedByteBuffer》发布之后,很多读者朋友私信我说,文章的信息量太大了,其中很多章节介绍的内容都是大家非常想要了解,并且是频繁被搜索的内容,所以根据读者朋友的建议,笔者决定将一些重要的章节内容独立出来,更好的方便大家检索。 关于MappedByteBuffer和FileChannel的话题,网上有很多,但大部分都在讨论MappedByteBuffer相较于传统FileChannel的优势,但好像很少有人来写一写MappedByteBuffer的劣势,所以笔者这里想写一点不一样的,来和大家讨论讨...

  QrTANuPTD5bh   2024年03月28日   30   0   0 Java

本文涉及到的内核源码版本为:5.4,JVM源码为:OpenJDK17,RocketMQ源码版本为:5.1.1 在之前的文章《一步一图带你深入剖析JDKNIOByteBuffer在不同字节序下的设计与实现》中,笔者为大家详细剖析了JDKBuffer的整个设计体系,从总体上来讲,JDKNIO为每一种Java基本类型定义了对应的Buffer类(boolean类型除外)。 而Buffer本质上其实是JDK对OS中某一段内存在Java语言层面上的封装,当然了,这里的内存指的是虚拟内存,我们需要从之前文章中的内核空间视角切换到用户空间上来,所以本文提到的内存如无特殊说明均是指虚拟内存。 JVM在操作...

  QrTANuPTD5bh   2024年03月19日   20   0   0 Java

本文基于内核5.4版本源码讨论 在前面两篇介绍mmap的文章中,笔者分别从原理角度以及源码实现角度带着大家深入到内核世界深度揭秘了mmap内存映射的本质。从整个mmap映射的过程可以看出,内核只是在进程的虚拟地址空间中寻找出一段空闲的虚拟内存区域vma然后分配给本次映射而已。 vma=vm_area_alloc(mm); vma->vm_start=addr; vma->vm_end=addr+len; vma->vm_flags=vm_flags; vma->vm_page_prot=vm_get_page_prot(vm_flags); vma->vm_p...

  QrTANuPTD5bh   2023年12月22日   16   0   0 Linux

本文基于内核5.4版本源码讨论 通过上篇文章《从内核世界透视mmap内存映射的本质(原理篇)》的介绍,我们现在已经非常清楚了mmap背后的映射原理以及它的使用方法,其核心就是在进程虚拟内存空间中分配一段虚拟内存出来,然后将这段虚拟内存与磁盘文件映射起来,整个mmap系统调用就结束了。 而在mmap内存映射的整个过程中,最为核心且复杂烧脑的环节其实不是内存映射的逻辑,而是虚拟内存分配的整个流程。笔者曾在之前的文章《深入理解Linux物理内存分配全链路实现》中详细地为大家介绍了物理内存的分配过程,那么虚拟内存的分配过程又是什么样的呢? 本文我们将进入到内核源码实现中,来看一下虚拟内存分配的过程...

  QrTANuPTD5bh   2023年11月02日   32   0   0 Linux

写在本文开始之前.... 从本文开始我们就正式开启了Linux内核内存管理子系统源码解析系列,笔者还是会秉承之前系列文章的风格,采用一步一图的方式先是详细介绍相关原理,在保证大家清晰理解原理的基础上,我们再来一步一步的解析相关内核源码的实现。有了源码的辅证,这样大家看得也安心,理解起来也放心,最起码可以证明笔者没有胡编乱造骗大家,哈哈 内存管理子系统可谓是Linux内核众多子系统中最为复杂最为庞大的一个,其中包含了众多繁杂的概念和原理,通过内存管理这条主线我们把可以把操作系统的众多核心系统给拎出来,比如:进程管理子系统,网络子系统,文件子系统等。 由于内存管理子系统过于复杂庞大,其中涉及到的众...

  QrTANuPTD5bh   2023年11月01日   68   0   0 Linux

1.前文回顾 在上篇文章《深入理解Linux虚拟内存管理》中,笔者分别从进程用户态和内核态的角度详细深入地为大家介绍了Linux内核如何对进程虚拟内存空间进行布局以及管理的相关实现。在我们深入理解了虚拟内存之后,那么何不顺带着也探秘一下物理内存的管理呢? 所以本文的目的是在深入理解虚拟内存管理的基础之上继续带大家向前奋进,一举击破物理内存管理的知识盲区,使大家能够俯瞰整个Linux内存管理子系统的整体全貌。 而在正式开始物理内存管理的主题之前,笔者觉得有必须在带大家回顾下上篇文章中介绍的虚拟内存管理的相关知识,方便大家来回对比虚拟内存和物理内存,从而可以全面整体地掌握Linux内存管理子系统。...

  QrTANuPTD5bh   2023年11月01日   43   0   0 Linux

前文回顾 在上篇文章《深入理解Linux物理内存管理》中,笔者详细的为大家介绍了Linux内核如何对物理内存进行管理以及相关的一些内核数据结构。 在介绍物理内存管理之前,笔者先从CPU的角度开始,介绍了三种Linux物理内存模型:FLATMEM平坦内存模型,DISCONTIGMEM非连续内存模型,SPARSEMEM稀疏内存模型。 随后笔者又带大家站在一个新的视角上,把物理内存看做成一个整体,从CPU访问物理内存以及CPU与物理内存的相对位置变化的角度介绍了两种物理内存架构:一致性内存访问UMA架构,非一致性内存访问NUMA架构。 在NUMA架构下,只有DISCONTIGMEM非连续...

  QrTANuPTD5bh   2023年11月01日   93   0   0 Linux

在上篇文章《深入理解Linux物理内存分配全链路实现》中,笔者为大家详细介绍了Linux内存分配在内核中的整个链路实现: 但是当内核执行到get_page_from_freelist函数,准备进入伙伴系统执行具体内存分配动作的相关逻辑,笔者考虑到文章篇幅的原因,并没有过多的着墨,算是留下了一个小尾巴。 那么本文笔者就为大家完整地介绍一下伙伴系统这部分的内容,我们将基于内核5.4版本的源码来详细的讨论一下伙伴系统在内核中的设计与实现。 1.伙伴系统的核心数据结构 如上图所示,内核会为NUMA节点中的每个物理内存区域zone分配一个伙伴系统用于管理该物理内存区域zone里的空闲内存页。 而伙...

  QrTANuPTD5bh   2023年11月01日   75   0   0 Linux

1.前文回顾 在之前的几篇内存管理系列文章中,笔者带大家从宏观角度完整地梳理了一遍Linux内存分配的整个链路,本文的主题依然是内存分配,这一次我们会从微观的角度来探秘一下Linux内核中用于零散小内存块分配的内存池——slab分配器。 在本小节中,笔者还是按照以往的风格先带大家简单回顾下之前宏观视角下Linux内存分配最为核心的内容,目的是让大家从宏观视角平滑地过度到微观视角,内容上有个衔接,不至于让大家感到突兀。 下面的内容我们只做简单回顾,大家不必纠缠细节,把握整体宏观流程 在《深入理解Linux物理内存分配与释放全链路实现》一文中,笔者以内核物理内存分配与释放的API为起点,详细为...

  QrTANuPTD5bh   2023年11月01日   60   0   0 Linux

在上篇文章《细节拉满,80张图带你一步一步推演slab内存池的设计与实现》中,笔者从slabcache的总体架构演进角度以及slabcache的运行原理角度为大家勾勒出了slabcache的总体架构视图,基于这个视图详细阐述了slabcache的内存分配以及释放原理。 slabcache机制确实比较复杂,涉及到的场景又很多,大家读到这里,我想肯定会好奇或者怀疑笔者在上篇文章中所论述的那些原理的正确性,毕竟talkischeap,所以为了让大家看着安心,理解起来放心,从本文开始,我们将正式进入showyouthecode的阶段。笔者会基于内核5.4版本,详细为大家剖析slabcache在内核中的...

  QrTANuPTD5bh   2023年11月01日   50   0   0 Linux

本文源码部分基于内核5.4版本讨论 在经过上篇文章《从内核源码看slab内存池的创建初始化流程》的介绍之后,我们最终得到下面这幅slabcache的完整架构图: 本文笔者将带大家继续从内核源码的角度继续拆解slabcache的实现细节,接下来笔者会基于上面这幅slabcache完整架构图,详细介绍一下slabcache是如何进行内存分配的。 1.slabcache如何分配内存 当我们使用fork()系统调用创建进程的时候,内核需要为进程创建task_struct结构,structtask_struct是内核中的核心数据结构,当然也会有专属的slabcache来进行管理,task_str...

  QrTANuPTD5bh   2023年11月01日   75   0   0 Linux

在上篇文章《深入理解slabcache内存分配全链路实现》中,笔者详细地为大家介绍了slabcache进行内存分配的整个链路实现,本文我们就来到了slabcache最后的一部分内容了,当申请的内存使用完毕之后,下面就该释放内存了。 在接下来的内容中,笔者为大家介绍一下内核是如何将内存块释放回slabcache的。我们还是先从slabcache释放内存的内核API开始聊起 内核提供了kmem_cache_free函数,用于将对象释放回其所属的slabcache中,参数x表示我们要释放的内存块(对象)的虚拟内存地址,参数s指向内存块所属的slabcache。 voidkmem_cache_fr...

  QrTANuPTD5bh   2023年11月01日   67   0   0 Linux

本文是笔者slab系列的最后一篇文章,为了方便大家快速检索,先将相关的文章列举出来: 《细节拉满,80张图带你一步一步推演slab内存池的设计与实现》 《从内核源码看slab内存池的创建初始化流程》 《深入理解slabcache内存分配全链路实现》 《深度解析slab内存池回收内存以及销毁全流程》 在之前的这四篇文章中,笔者详细的为大家介绍了slab内存池的整体架构演化过程,随后基于这个演化过程,介绍了整个slaballoactor体系的创建,内存分配,内存释放以及销毁等相关复杂流程在内核中的实现。 我们知道slab内存池是专门为了应对内核中关于小内存分配需求而应运而生的,内核会为每一个...

  QrTANuPTD5bh   2023年11月01日   66   0   0 Linux

本文基于内核5.4版本源码讨论 之前有不少读者给笔者留言,希望笔者写一篇文章介绍下mmap内存映射相关的知识体系,之所以迟迟没有动笔,是因为mmap这个系统调用看上去简单,实际上并不简单,可以说是非常复杂的一个系统调用。 如果想要给大家把mmap背后的技术本质,正确地,清晰地还原出来,还是有一定难度的,因为mmap这一个系统调用就能撬动起整个内存管理系统,文件系统,页表体系,缺页中断等一大片的背景知识,涉及到的知识面广且繁杂。 幸运的是这一整套的背景知识,笔者已经在《聊聊Linux内核》系列文章中为大家详细介绍过了,所以现在是时候开始动笔了,不过大家不需要担心,虽然涉及到的背景知识比较多,...

  QrTANuPTD5bh   2023年11月01日   17   0   0 Linux
关注 更多

空空如也 ~ ~

粉丝 更多

空空如也 ~ ~