<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[bin的技术小屋]]></title><description><![CDATA[]]></description><link>https://blog.csdn.net/weixin_47282449</link><language>zh-cn</language><generator>https://blog.csdn.net/</generator><copyright><![CDATA[Copyright &copy; weixin_47282449]]></copyright><item><title><![CDATA[时间轮在 Netty , Kafka 中的设计与实现]]></title><link>https://blog.csdn.net/weixin_47282449/article/details/144710839</link><guid>https://blog.csdn.net/weixin_47282449/article/details/144710839</guid><author>weixin_47282449</author><pubDate>Wed, 25 Dec 2024 10:03:48 +0800</pubDate><description><![CDATA[本文我们主要讨论了定时任务调度相关的主题，笔者一开始介绍了 JDK 的三种调度组件：Timer，DelayQueue，ScheduledThreadPoolExecutor。但他们的共同特点都是采用了小根堆这种数据结构来组织管理定时任务，然而在面对海量定时任务的添加与取消时，这种设计的时间复杂度会比较高 ——O(logn)。随后笔者介绍了 Netty 的单层时间轮 HashedWheelTimer，它将海量定时任务的添加与取消操作的时间复杂度降低到了O(1)]]></description><category></category></item><item><title><![CDATA[Netty 如何自动探测内存泄露的发生]]></title><link>https://blog.csdn.net/weixin_47282449/article/details/143587460</link><guid>https://blog.csdn.net/weixin_47282449/article/details/143587460</guid><author>weixin_47282449</author><pubDate>Thu, 07 Nov 2024 10:23:25 +0800</pubDate><description><![CDATA[要想触发 Netty 的内存泄露探测机制需要同时满足以下五个条件：应用必须开启内存泄露探测功能。必须要等到 ByteBuf 被 GC 之后，内存泄露才能探测的到，如果 GC 一直没有触发，那么即使是 ByteBuf 没有任何强引用或者软引用了，内存泄露的探测也将无从谈起。当 GC 发生之后，必须是要等到下一次分配内存的时候，才会触发内存泄露的探测。如果没有内存申请的行为发生，那么内存泄露的探测也不会发生。Netty 并不会探测每一个 ByteBuf 的泄露情况，而是根据一定的采样间隔，进行采样探测。]]></description><category></category></item><item><title><![CDATA[谈一谈 Netty 的内存管理 —— 且看 Netty 如何实现 Java 版的 Jemalloc]]></title><link>https://blog.csdn.net/weixin_47282449/article/details/143230669</link><guid>https://blog.csdn.net/weixin_47282449/article/details/143230669</guid><author>weixin_47282449</author><pubDate>Fri, 25 Oct 2024 11:39:54 +0800</pubDate><description><![CDATA[深度剖析 Linux 伙伴系统的设计与实现》《细节拉满，80 张图带你一步一步推演 slab 内存池的设计与实现》《深度解读 Linux 内核级通用内存池 —— kmalloc 体系》好了，今天的内容就到这里，我们下篇文章见~~~]]></description><category></category></item><item><title><![CDATA[小小的引用计数，大大的性能考究]]></title><link>https://blog.csdn.net/weixin_47282449/article/details/141355320</link><guid>https://blog.csdn.net/weixin_47282449/article/details/141355320</guid><author>weixin_47282449</author><pubDate>Tue, 20 Aug 2024 12:35:49 +0800</pubDate><description><![CDATA[到这里，Netty 对引用计数的精彩设计，笔者就为大家完整的剖析完了，一共有四处非常精彩的优化设计，我们总结如下：使用性能更优的  XADD 指令来替换 CMPXCHG 指令。引用计数采用了奇偶设计，保证了并发语义。采用性能更优的==运算来替换运算。能不走内存屏障就尽量不走内存屏障。]]></description><category></category></item><item><title><![CDATA[聊一聊 Netty 数据搬运工 ByteBuf 体系的设计与实现]]></title><link>https://blog.csdn.net/weixin_47282449/article/details/141184389</link><guid>https://blog.csdn.net/weixin_47282449/article/details/141184389</guid><author>weixin_47282449</author><pubDate>Wed, 14 Aug 2024 10:39:51 +0800</pubDate><description><![CDATA[本文笔者从八个角度为大家详细的剖析了 ByteBuf 的整体设计，这八个角度分别是：内存区域分布的角度，内存管理的角度，内存访问的角度，内存回收的角度，内存统计 Metric 的角度，零拷贝的角度，引用计数的角度，扩容的角度。到现在为止，我们只是扫清了 Netty 内存管理外围的一些障碍，那么下一篇文章，笔者将带大家深入到内存管理的核心，彻底让大家弄懂 Netty 的内存管理机制。好了，本文的内容就到这里，我们下篇文章见~~~]]></description><category></category></item><item><title><![CDATA[PhantomReference 和 WeakReference 究竟有何不同]]></title><link>https://blog.csdn.net/weixin_47282449/article/details/139813947</link><guid>https://blog.csdn.net/weixin_47282449/article/details/139813947</guid><author>weixin_47282449</author><pubDate>Wed, 19 Jun 2024 21:57:20 +0800</pubDate><description><![CDATA[PhantomReference 和 WeakReference 如果仅仅从概念上来说其实很难区别出他们之间究竟有何不同，比如， PhantomReference 是用来跟踪对象是否被垃圾回收的，如果对象被 GC ，那么其对应的 PhantomReference 就会被加入到一个 ReferenceQueue 中，这个 ReferenceQueue 是在创建 PhantomReference 对象的时候注册进去的。后面的套路和 PhantomReference 一模一样。]]></description><category></category></item><item><title><![CDATA[FinalReference 如何使 GC 过程变得拖拖拉拉]]></title><link>https://blog.csdn.net/weixin_47282449/article/details/139754629</link><guid>https://blog.csdn.net/weixin_47282449/article/details/139754629</guid><author>weixin_47282449</author><pubDate>Mon, 17 Jun 2024 21:08:29 +0800</pubDate><description><![CDATA[从整个 JVM 对于 FinalReference 的处理过程可以看出，只要我们在一个 Java 类中重写了 finalize() 方法，那么当这个 Java 类对应的实例可以被回收的时候，它的  finalize() 方法是一定会被调用的。调用的时机取决于 FinalizerThread 线程什么时候被 OS 调度到，但是从另外一个侧面也可以看出，由于 FinalReference 的影响，一个原本该被回收的对象，在 GC 的过程又会被 JVM 复活。]]></description><category></category></item><item><title><![CDATA[SoftReference 到底在什么时候被回收 ？ 如何量化内存不足 ？]]></title><link>https://blog.csdn.net/weixin_47282449/article/details/139707232</link><guid>https://blog.csdn.net/weixin_47282449/article/details/139707232</guid><author>weixin_47282449</author><pubDate>Sat, 15 Jun 2024 19:39:46 +0800</pubDate><description><![CDATA[从以上过程中我们可以看出，SoftReference 被 ZGC 回收的精确时机是，当一个 SoftReference 对象已经很久很久没有被应用线程访问到了，那么发生 GC 的时候这个 SoftReference 就会被回收掉。具体多久呢?就是 _max_interval 指定的 SoftReference 最大存活时间，这个时间由当前 JVM 堆的最大剩余空间和共同决定。]]></description><category></category></item><item><title><![CDATA[以 ZGC 为例，谈一谈 JVM 是如何实现 Reference 语义的]]></title><link>https://blog.csdn.net/weixin_47282449/article/details/139650435</link><guid>https://blog.csdn.net/weixin_47282449/article/details/139650435</guid><author>weixin_47282449</author><pubDate>Thu, 13 Jun 2024 11:48:47 +0800</pubDate><description><![CDATA[本文我们首先从中间件的角度，介绍了 SoftReference，WeakReference，PhantomReference，FinalReference 这些 Java 中定义的 Reference 的相关概念及其应用场景。后面我们从中间件的视角转入到 JDK 中，介绍了 Cleaner，Finalizer，ReferenceHandler 线程，FinalizerThread 线程，ReferenceQueue 等在 JDK 层面处理 Reference 对象的重要设计。]]></description><category></category></item><item><title><![CDATA[System.gc 之后到底发生了什么 ？]]></title><link>https://blog.csdn.net/weixin_47282449/article/details/137244897</link><guid>https://blog.csdn.net/weixin_47282449/article/details/137244897</guid><author>weixin_47282449</author><pubDate>Mon, 01 Apr 2024 20:03:24 +0800</pubDate><description><![CDATA[本文基于 OpenJDK17 进行讨论在 JDK NIO 针对堆外内存的分配场景中，我们经常会看到 System.gc 的身影，比如当我们通过对文件进行内存映射的时候，如果 JVM 进程虚拟内存空间中的虚拟内存不足，JVM 在 native 层就会抛出。当 JDK 捕获到异常的时候，就会意识到此时进程虚拟内存空间中的虚拟内存已经不足了，无法支持本次内存映射，于是就会调用System.gc。]]></description><category></category></item><item><title><![CDATA[MappedByteBuffer VS FileChannel：从内核层面对比两者的性能差异]]></title><link>https://blog.csdn.net/weixin_47282449/article/details/137107964</link><guid>https://blog.csdn.net/weixin_47282449/article/details/137107964</guid><author>weixin_47282449</author><pubDate>Thu, 28 Mar 2024 12:43:40 +0800</pubDate><description><![CDATA[本文基于 Linux 内核 5.4 版本进行讨论自上篇文章发布之后，很多读者朋友私信我说，文章的信息量太大了，其中很多章节介绍的内容都是大家非常想要了解，并且是频繁被搜索的内容，所以根据读者朋友的建议，笔者决定将一些重要的章节内容独立出来，更好的方便大家检索。]]></description><category></category></item><item><title><![CDATA[从 Linux 内核角度探秘 JDK MappedByteBuffer]]></title><link>https://blog.csdn.net/weixin_47282449/article/details/136852501</link><guid>https://blog.csdn.net/weixin_47282449/article/details/136852501</guid><author>weixin_47282449</author><pubDate>Tue, 19 Mar 2024 19:21:45 +0800</pubDate><description><![CDATA[在之前的文章《一步一图带你深入剖析 JDK NIO ByteBuffer 在不同字节序下的设计与实现》 中，笔者为大家详细剖析了 JDK Buffer 的整个设计体系，从总体上来讲，JDK NIO 为每一种 Java 基本类型定义了对应的 Buffer 类（boolean 类型除外）。而 Buffer 本质上其实是 JDK  对 OS  中某一段内存在 Java 语言层面上的封装，当然了，这里的内存指的是虚拟内存，我们需要从之前文章中的内核空间视角切换到用户空间上来，所以本文提到的内存如无特殊说明均是指虚拟]]></description><category></category></item><item><title><![CDATA[一文聊透 Linux 缺页异常的处理 —— 图解 Page Faults]]></title><link>https://blog.csdn.net/weixin_47282449/article/details/135166710</link><guid>https://blog.csdn.net/weixin_47282449/article/details/135166710</guid><author>weixin_47282449</author><pubDate>Sat, 23 Dec 2023 11:51:47 +0800</pubDate><description><![CDATA[在前面两篇介绍 mmap 的文章中，笔者分别从原理角度以及源码实现角度带着大家深入到内核世界深度揭秘了 mmap 内存映射的本质。从整个 mmap 映射的过程可以看出，内核只是在进程的虚拟地址空间中寻找出一段空闲的虚拟内存区域 vma 然后分配给本次映射而已。
如果是文件映射的话，内核还会额外做一项工作，就是将分配出来的这段虚拟内存区域 vma 与映射文件关联映射起来。
映射的核心就是将虚拟内存区域 vm_area_struct 相关的内存操作  设置为文件系统的相关操作 。这样一来，进程后续对这段虚拟内存]]></description><category></category></item><item><title><![CDATA[从内核世界透视 mmap 内存映射的本质（源码实现篇）]]></title><link>https://blog.csdn.net/weixin_47282449/article/details/133743261</link><guid>https://blog.csdn.net/weixin_47282449/article/details/133743261</guid><author>weixin_47282449</author><pubDate>Tue, 10 Oct 2023 11:29:10 +0800</pubDate><description><![CDATA[到现在为止，笔者通过两篇文章，一篇原理，一篇源码，深入到内核世界中，将 mmap 内存映射的本质给大家呈现了出来，知识点比较密集且比较烧脑，因此笔者又画了一副 mmap 内存映射的整体思维导图方便大家回顾。在原理篇中笔者首先通过五个角度为大家详细介绍了 mmap 的使用方法及其在内核中的实现原理，这五个角度分别是：私有匿名映射，其主要用于进程申请虚拟内存，以及初始化进程虚拟内存空间中的 BSS 段，堆，栈这些虚拟内存区域。]]></description><category></category></item><item><title><![CDATA[从内核世界透视 mmap 内存映射的本质（原理篇）]]></title><link>https://blog.csdn.net/weixin_47282449/article/details/132991295</link><guid>https://blog.csdn.net/weixin_47282449/article/details/132991295</guid><author>weixin_47282449</author><pubDate>Mon, 18 Sep 2023 18:33:10 +0800</pubDate><description><![CDATA[本文笔者从五个角度为大家详细介绍了 mmap 的使用方法及其在内核中的实现原理，这五个角度分别是：私有匿名映射，其主要用于进程申请虚拟内存，以及初始化进程虚拟内存空间中的 BSS 段，堆，栈这些虚拟内存区域。私有文件映射，其核心特点是背后映射的文件页在多进程之间是读共享的，多个进程对各自虚拟内存区的修改只能反应到各自对应的文件页上，而且各自的修改在进程之间是互不可见的，最重要的一点是这些修改均不会回写到磁盘文件中。]]></description><category></category></item><item><title><![CDATA[一步一图带你构建 Linux 页表体系 —— 详解虚拟内存如何与物理内存进行映射]]></title><link>https://blog.csdn.net/weixin_47282449/article/details/131856313</link><guid>https://blog.csdn.net/weixin_47282449/article/details/131856313</guid><author>weixin_47282449</author><pubDate>Fri, 21 Jul 2023 17:11:12 +0800</pubDate><description><![CDATA[本文笔者通过页表体系这条主线脉络，为大家串讲了一下之前介绍的虚拟内存管理以及物理内存管理的相关内容，在我们回顾完虚拟内存管理和物理内存管理之后，随后我们引出了虚拟内存如何与物理内存进行映射这个问题，并在这个过程中为大家揭露了页表的本质。在我们清楚了页表的本质之后，笔者又沿着页表体系的演进这条主线，对单级页表，二级页表，四级页表展开了介绍，其中花了一定的篇幅为大家详细的介绍了 32 位和 64 位页表项以及页目录想的比特位布局，让大家真真实实的看到了页表项和页目录项到底长什么样子。]]></description><category></category></item><item><title><![CDATA[深度解读 Linux 内核级通用内存池 —— kmalloc 体系]]></title><link>https://blog.csdn.net/weixin_47282449/article/details/131324720</link><guid>https://blog.csdn.net/weixin_47282449/article/details/131324720</guid><author>weixin_47282449</author><pubDate>Wed, 21 Jun 2023 11:35:54 +0800</pubDate><description><![CDATA[整个 kmalloc 通用内存池体系的核心是围绕着 kmalloc_caches 这个二维数组召开的。其中一维数组中定义的是  kmalloc 内存池中的内存来源，在内核中使用。]]></description><category></category></item><item><title><![CDATA[深度解析 slab 内存池回收内存以及销毁全流程]]></title><link>https://blog.csdn.net/weixin_47282449/article/details/130883805</link><guid>https://blog.csdn.net/weixin_47282449/article/details/130883805</guid><author>weixin_47282449</author><pubDate>Fri, 26 May 2023 11:44:06 +0800</pubDate><description><![CDATA[整个 slab cache 系列篇幅非常庞大，涉及到的细节非常丰富，为了方便大家回顾，笔者这里将 slab cache 系列涉及到的重点内容再次梳理总结一下。]]></description><category></category></item><item><title><![CDATA[深入理解 slab cache 内存分配全链路实现]]></title><link>https://blog.csdn.net/weixin_47282449/article/details/130503907</link><guid>https://blog.csdn.net/weixin_47282449/article/details/130503907</guid><author>weixin_47282449</author><pubDate>Fri, 05 May 2023 11:50:14 +0800</pubDate><description><![CDATA[本文我们基于 slab cache 的完整的架构，近一步深入到内核源码中详细介绍了 slab cache 关于内存分配的完整流程：我们可以看到 slab cache 内存分配的整个流程分为 fastpath 快速路径和 slowpath 慢速路径。其中在 fastpath 路径下，内核会直接从 slab cache 的本地 cpu 缓存中获取内存块，这是最快的一种方式。从本地 cpu 缓存 partial 列表中分配从 NUMA 节点缓存中分配，其中涉及到了对本地 cpu 缓存的填充。]]></description><category></category></item><item><title><![CDATA[从内核源码看 slab 内存池的创建初始化流程]]></title><link>https://blog.csdn.net/weixin_47282449/article/details/130100907</link><guid>https://blog.csdn.net/weixin_47282449/article/details/130100907</guid><author>weixin_47282449</author><pubDate>Wed, 12 Apr 2023 10:22:52 +0800</pubDate><description><![CDATA[本文笔者基于内核 5.4 版本，从源码角度详细讨论了 slab cache 的创建初始化过程，创建流程如下图所示：经过该流程的创建之后，我们得到了如下图所示的 slab cache 架构：在这个过程中，笔者又近一步从源码角度介绍了内核具体是如何对 slab 对象进行内存布局的。在这个内存布局的基础上，笔者又近一步展开了内核如何计算一个 slab 到底需要多少个物理内存页，以及一个 slab 到底能够容纳多少内存块的相关逻辑。]]></description><category></category></item></channel></rss>