1. 程式人生 > >深入淺出Netty記憶體管理:PoolChunkList

深入淺出Netty記憶體管理:PoolChunkList

前面兩篇分別分析了PoolChunk和PoolSubpage的實現,本文主要分析管理PoolChunk生命週期的PoolChunkList。

PoolChunkList

PoolChunkList負責管理多個chunk的生命週期,在此基礎上對記憶體分配進行進一步的優化。

12345678910 finalclassPoolChunkList<T>implementsPoolChunkListMetric{privatefinalPoolChunkList<T>nextList;privatefinalintminUsage;privatefinalintmaxUsage;privatePoolChunk<T>head;privatePoolChunkList<T>prevList;...}

從程式碼實現可以看出,每個PoolChunkList例項維護了一個PoolChunk連結串列,自身也形成一個連結串列,為何要這麼實現?

2184951-c5a5bf6c03d86ce0

隨著chunk中page的不斷分配和釋放,會導致很多碎片記憶體段,大大增加了之後分配一段連續記憶體的失敗率,針對這種情況,可以把記憶體使用率較大的chunk放到PoolChunkList連結串列更後面,具體實現如下:

12345678910111213141516171819202122 booleanallocate(PooledByteBuf<T>buf,intreqCapacity,intnormCapacity){if(head==null){returnfalse;}for(PoolChunk<T>cur=head;;){longhandle=cur.allocate(normCapacity);if(handle<0){cur=cur.next;if(cur==null){returnfalse;}}else{cur.initBuf(buf,handle,reqCapacity);if(cur.usage()>=maxUsage){// (1)remove(cur);nextList.add(cur);}returntrue;}}}

假設poolChunkList中已經存在多個chunk。當分配完記憶體後,如果當前chunk的使用量超過maxUsage,則把該chunk從當前連結串列中刪除,新增到下一個連結串列中。

但是,隨便chunk中記憶體的釋放,其記憶體使用率也會隨著下降,當下降到minUsage時,該chunk會移動到前一個列表中,實現如下:

1234567891011121314 booleanfree(PoolChunk<T>chunk,longhandle){chunk.free(handle);if(chunk.usage()<minUsage){remove(chunk);if(prevList==null){assertchunk.usage()==0;returnfalse;}else{prevList.add(chunk);returntrue;}}returntrue;}

從poolChunkList的實現可以看出,每個chunkList的都有一個上下限:minUsage和maxUsage,兩個相鄰的chunkList,前一個的maxUsage和後一個的minUsage必須有一段交叉值進行緩衝,否則會出現某個chunk的usage處於臨界值,而導致不停的在兩個chunk間移動。

所以chunk的生命週期不會固定在某個chunkList中,隨著記憶體的分配和釋放,根據當前的記憶體使用率,在chunkList連結串列中前後移動。

相關推薦

深入淺出Netty記憶體管理PoolChunkList

前面兩篇分別分析了PoolChunk和PoolSubpage的實現,本文主要分析管理PoolChunk生命週期的PoolChunkList。 PoolChunkList PoolChunkList負責管理多個chunk的生命週期,在此基礎上對記憶體分配進行進一步的優化。

深入淺出Netty記憶體管理PoolSubpage

本系列: 上一節中分析瞭如何在poolChunk中分配一塊大於pageSize的記憶體,但在實際應用中,存在很多分配小記憶體的情況,如果也佔用一個page,明顯很浪費。針對這種情況,Netty提供了PoolSubpage把poolChunk的一個page節點8k

深入淺出Netty記憶體管理PoolChunk

多年之前,從C記憶體的手動管理上升到java的自動GC,是歷史的巨大進步。然而多年之後,netty的記憶體實現又曲線的回到了手動管理模式,正印證了馬克思哲學觀:社會總是在螺旋式前進的,沒有永遠的最好。的確,就記憶體管理而言,GC給程式設計師帶來的價值是不言而喻的,

深入淺出Netty記憶體管理PoolArena

前面分別分析了PoolChunk、PoolSubpage和PoolChunkList,本文主要分析PoolArena。 PoolArena 應用層的記憶體分配主要通過如下實現,但最終還是委託給PoolArena實現。 PooledByteBufAllocat

資料庫記憶體管理tcmalloc與jemalloc

  [[email protected] ~]# tar zxvf libunwind-1.2.1.tar.gz  [[email protected] ~]# cd libunwind-1.2

Sqlserver記憶體管理限制最大佔用記憶體

一、Sqlserver對系統記憶體的管理原則是:按需分配,且貪婪(用完不還)。它不會自動釋放記憶體,因此執行結果集大的sql語句時,資料取出後,會一直佔用記憶體,直到佔滿機器記憶體(並不會撐滿,還是有個最大限制,比機器記憶體稍小),在重啟服務前,sqlserver不會釋放該記

Spark靜態記憶體管理StaticMemoryManager

例如Executor的可用Heap大小是10G,實際上Spark只能使用90%,也就是9G的大小,是由spark.storage.safetyFraction來控制。 Spark1.6.X以前JVM到底可以快取多少資料? (1)單個Executor的Cache資料量計算公式: Heap Size * spar

iOS效能優化之記憶體管理Analyze、Leaks、Allocations的使用和案例程式碼

一. 一些相關概念 1.記憶體空間的劃分: 我們知道,一個程序佔用的記憶體空間,包含5種不同的資料區:(1)BSS段:通常是存放未初始化的全域性變數;(2)資料段:通常是存放已初始化的全域性變數。(3)程式碼段:通常是存放程式執行程式碼。(4)堆:通常是用於存放程序執行中被

Linux記憶體管理HighMemory

HighMemory介紹 Linux一般把整個4GB可以map的記憶體中的1GB用於低端記憶體。從0xC0000000開始的話(CONFIG_PAGE_OFFSET配置),低端記憶體的地址範圍就是0xC0000000到high_memory地址。 high_

iOS記憶體管理記憶體洩露除錯的常用技巧

在往下看之前請下載例項MemoryProblems,我們將以這個工程展開如何檢查和解決記憶體問題。 懸掛指標問題 懸掛指標(Dangling Pointer)就是當指標指向的物件已經釋放或回收後,但沒有對指標做任何修改(一般來說,將它指向空指標),而是仍然指向原來已經回收的地址。如

JVM記憶體管理記憶體區域和記憶體洩漏

VM執行時資料區域 JVM執行Java程式的過程中,會使用到各種資料區域,這些區域有各自的用途、建立和銷燬時間。根據《Java虛擬機器規範(第二版)》(下文稱VM Spec)的規定,JVM包括下列幾個執行時資料區域: 1.程式計數器(Program Counter Register): 每一個Java執

Linux記憶體管理CMA

某些驅動需要用到一大塊連續的實體記憶體,但使用kmalloc等很分配很大的連續記憶體。 所以這裡有一種三星實現叫CMA的方式,來連續的大記憶體分配。 Why is it needed? Issue 1: Camera, Video Codec等Multimedia Device需要連續的數MB大小的Me

C語言動態記憶體管理malloc、realloc、calloc以及free函式

我們已經掌握的記憶體開闢方式有: int val = 20;//在棧空間上開闢四個位元組 char arr[10] = {0};//在棧空間上開闢10個位元組的連續空間 但是這種開闢空間的方式有兩個特點: 1. 空間開闢的大小是固定的。

作業系統的學習(2)——實體記憶體管理連續記憶體分配

記憶體的最小訪問單位是位元組(8it),一般計算機系統是32位匯流排,一次讀寫可以讀或者寫32位也就是4位元組。 CPU裡會看到快取記憶體,快取記憶體就是在進行讀寫指令或者指令執行的過程中,訪問資料都需要從記憶體中讀資料,如果這時候有大量資料需要讀寫或者重複利

7.netty記憶體管理-ByteBuf

ByteBuf ByteBuf是什麼 ByteBuf重要API read、write、set、skipBytes mark和reset duplicate、slice、copy retain、release ByteBuf擴容 ByteBuf種類 ByteBufAllocate UnPooledB

談談Netty記憶體管理

## 前言 正是Netty的易用性和高效能成就了Netty,讓其能夠如此流行。 而作為一款通訊框架,首當其衝的便是對IO效能的高要求。 不少讀者都知道Netty底層通過使用Direct Memory,減少了核心態與使用者態之間的記憶體拷貝,加快了IO速率。但是頻繁的向系統申請Direct Memory

第四節FreeRTOS 記憶體管理

目錄 記憶體管理的介紹 記憶體碎片 Heap_1-5記憶體分配的區別 Heap_1:適用於一旦建立好記憶體,就不刪除的任務。       (本質是分配的大陣列做記憶體堆.) Heap_2:適用於重複分配和刪除具有相同堆疊空間任務。(本質是分配的大

QEMU深入淺出: guest實體記憶體管理

原  文:http://blog.vmsplice.net/2016/01/qemu-internals-how-guest-physical-ram.html 作  者:Stefan Hajnoczi 領  域:Open source and virtuali

現代作業系統第三章 記憶體管理

作業系統的工作是將這個儲存體系抽象成為一個有用的模型並將管理這個抽象模型 作業系統中管理分層儲存體系的部分稱為儲存管理器。它的任務是有效的管理記憶體,即記錄哪些記憶體是正在使用的,哪些記憶體是空閒的,在程序需要時為其分配記憶體,在程序使用完成的時候為其釋放記憶體。 3.1 無儲存器的

深入淺出 Java 中 JVM 記憶體管理

  Java崗位面試,JVM是對程式設計師基本功考察,通常會問你對JVM瞭解嗎?   可以分幾部分回答這個問題,首先JVM記憶體劃分 | JVM垃圾回收的含義  |  有哪些GC演算法  以及年輕代和老年代各自特點等