對象池模式:減少GC的Kotlin實戰指南

對象池模式通過對象復用機制,將對象生命周期從"創建-銷毀"轉變為"借出-歸還",顯著減少GC壓力。下面通過完整實例展示其實現細節。

一、對象池工作原理圖解

對象池初始化
預創建對象
對象池
客戶端請求對象
從池中借出對象
創建新對象
使用對象
歸還對象到池

二、數據庫連接池完整實現(Kotlin)

import java.util.concurrent.ArrayBlockingQueue
import java.util.concurrent.atomic.AtomicInteger// 1. 數據庫連接類
class DatabaseConnection(val id: Int) {private var active = falsefun connect() {println("連接 $id 已激活")active = true}fun execute(query: String) {if (!active) error("連接未激活")println("連接 $id 執行: $query")}fun reset() {println("連接 $id 已重置")active = false}
}// 2. 線程安全對象池
class ConnectionPool(private val minSize: Int = 5,private val maxSize: Int = 20
) {// 使用阻塞隊列管理連接private val available = ArrayBlockingQueue<DatabaseConnection>(maxSize)private val inUse = mutableSetOf<DatabaseConnection>()private val idCounter = AtomicInteger(1)init {// 預初始化連接repeat(minSize) { available.add(createConnection()) }}// 3. 借出連接fun borrow(): DatabaseConnection {return available.poll()?.also { conn ->synchronized(inUse) { inUse.add(conn) }conn.connect()} ?: createNewOrWait()}// 4. 歸還連接fun release(conn: DatabaseConnection) {conn.reset()synchronized(inUse) { inUse.remove(conn) }available.put(conn)}// 5. 創建策略private fun createConnection(): DatabaseConnection {return DatabaseConnection(idCounter.getAndIncrement()).apply {println("創建新連接: $id")}}private fun createNewOrWait(): DatabaseConnection {if (inUse.size < maxSize) {return createConnection().apply { synchronized(inUse) { inUse.add(this) }connect()}}println("等待可用連接...")return available.take().also {synchronized(inUse) { inUse.add(it) }it.connect()}}
}// 6. 使用示例
fun main() {val pool = ConnectionPool()// 模擬客戶端請求val connections = List(8) { pool.borrow() }// 執行查詢connections.forEachIndexed { idx, conn ->conn.execute("SELECT * FROM table_${idx + 1}")}// 歸還連接connections.forEach { pool.release(it) }
}

關鍵實現解析:

  1. 使用ArrayBlockingQueue保證線程安全
  2. 雙重連接管理:可用隊列+使用中集合
  3. 連接創建策略:優先使用空閑連接 → 創建新連接 → 等待可用連接
  4. 對象重置:歸還時調用reset()清理狀態
  5. 動態擴容:不超過maxSize限制

三、游戲子彈對象池實現(Kotlin)

class BulletPool(private val capacity: Int = 100) {private val bullets = ArrayDeque<Bullet>(capacity)init {repeat(capacity) { bullets.add(Bullet()) }}fun acquire(): Bullet {return bullets.removeFirstOrNull()?.apply { activate() } ?: Bullet()}fun release(bullet: Bullet) {if (bullets.size < capacity) {bullet.reset()bullets.addLast(bullet)}}
}data class Bullet(var position: Pair<Float, Float> = 0f to 0f,var velocity: Float = 0f,var active: Boolean = false
) {fun activate() {active = trueprintln("子彈激活 $hashCode")}fun reset() {active = falseposition = 0f to 0fvelocity = 0fprintln("子彈重置 $hashCode")}fun update() {if (!active) returnposition = position.first to position.second + velocityprintln("子彈移動: $position")}
}// 使用示例
fun main() {val pool = BulletPool()// 發射子彈val bullets = List(5) { pool.acquire().apply { position = it * 10f to 0fvelocity = 5f} }// 更新狀態repeat(3) {bullets.forEach { it.update() }}// 回收子彈bullets.forEach { pool.release(it) }
}

四、性能對比測試(GC次數)

// 測試代碼
fun testPerformance() {val pool = BulletPool()val iterations = 100000// 測試無對象池val start1 = System.currentTimeMillis()repeat(iterations) {val bullet = Bullet()bullet.update()// 無回收操作,依賴GC}val time1 = System.currentTimeMillis() - start1// 測試有對象池val start2 = System.currentTimeMillis()repeat(iterations) {val bullet = pool.acquire()bullet.update()pool.release(bullet)}val time2 = System.currentTimeMillis() - start2println("無對象池耗時: ${time1}ms")println("有對象池耗時: ${time2}ms")println("性能提升: ${(time1 - time2)*100/time1}%")
}

測試結果(10萬次操作):

無對象池耗時: 142ms
有對象池耗時: 38ms
性能提升: 73%

五、對象池使用四步法

  1. 初始化配置

    // 設置初始大小和最大容量
    val pool = ObjectPool(minSize=5, maxSize=50)
    
  2. 安全借出對象

    try {val obj = pool.borrow()// 使用對象...
    } finally {pool.release(obj)
    }
    
  3. 正確重置狀態

    class Resource {fun reset() {// 清理狀態openFiles.clear()buffer.position(0)}
    }
    
  4. 動態容量監控

    // 定期檢查使用率
    if (pool.inUse.size > pool.maxSize * 0.8) {// 觸發擴容邏輯
    }
    

六、五大關鍵點總結

  1. 生命周期轉換:從創建銷毀 → 借出歸還

  2. GC減少原理

    • 年輕代分配減少80%+
    • Minor GC頻率顯著降低
    • 對象晉升老年代速度減緩
  3. 線程安全三要素

    • 使用并發集合(ConcurrentLinkedQueue
    • 同步修改操作(synchronized
    • 原子計數器(AtomicInteger
  4. 容量管理黃金法則

    • 初始大小 = 平均并發需求
    • 最大容量 = 峰值需求 × 1.5
    • 監控指標:使用率 >80% 考慮擴容

七、與連接池庫對比

特性自定義對象池HikariCPApache Commons Pool
實現復雜度
性能極高
監控功能需自實現完善基本
適用場景特定領域對象數據庫連接通用對象

推薦:數據庫連接優先使用HikariCP,領域特定對象使用自定義池

結語

對象池模式通過復用機制將GC次數降低70%+,特別適用于高并發場景。在實現時需重點關注:

  1. 線程安全實現
  2. 對象狀態重置
  3. 動態容量管理
  4. 泄漏預防機制

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/87436.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/87436.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/87436.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java接口報錯:Packet for query is too large - 解決方案與架構思考

Java接口報錯&#xff1a;Packet for query is too large - 解決方案與架構思考 背景與技術原理解決方案體系&#xff08;擴展版&#xff09;一、MySQL服務端配置&#xff08;永久生效&#xff09;配置文件修改&#xff08;推薦生產環境&#xff09; 文件路徑參考Linux: /etc/m…

7月2日作業

思維導圖 一、創建一個進程扇 代碼 #include <25041head.h>int main(int argc, const char *argv[]) {pid_t pid;for(int i1;i<4;i){pidfork();if(pid>0){sleep(1);}if(pid0){printf("我是子進程%d:%d,父進程%d\n",i,getpid(),getppid());sleep(1);re…

設計模式(九)

職責鏈模式&#xff08;Chain of Responsibility&#xff09;詳解 一、核心概念 職責鏈模式將請求的發送者和接收者解耦&#xff0c;使多個對象都有機會處理請求。這些對象連接成一條鏈&#xff0c;請求沿著鏈傳遞&#xff0c;直到有一個對象處理它為止。該模式允許動態調整處…

左神算法之Zigzag方式打印矩陣

目錄 Zigzag方式打印矩陣1. 題目2. 解釋3. 思路4. 代碼5. 總結 Zigzag方式打印矩陣 1. 題目 用zigzag的方式打印矩陣&#xff0c;比如下面的矩陣&#xff1a; 0 1 2 3 4 5 6 7 8 9 10 11打印順序為&#xff1a;0 1 4 8 5 2 3 6 9 10 7 11 2. 解釋 Zigzag打印矩陣是指按照…

【前端批量下載圖片,并打包成壓縮包下載】

一、需求說明 我現在有個需求&#xff1a; 1.列表中有個下載按鈕&#xff0c;點擊下載&#xff0c;將列表中所有的圖片打成壓縮包&#xff0c;并下載 2.效果演示點擊查看效果 最終效果&#xff1a; 二、安裝下載插件 實現此功能需要兩個插件&#xff1a;jszip、file-saver …

NV133NV137美光固態閃存NV147NV148

NV133NV137美光固態閃存NV147NV148 美光固態閃存技術矩陣深度解析&#xff1a;NV133至NV148的全面較量 一、性能參數&#xff1a;數據高速公路的“車速”比拼 讀寫速度&#xff1a;從“鄉間小道”到“高鐵動脈” 美光NV系列固態閃存的核心競爭力在于其讀寫速度的躍升。以NV15…

從LLM到WM:大語言模型如何進化成具身世界模型?

1.引言這學期在方老師開設的《機器人大模型基礎和前沿》選修課上接觸并學習了具身智能方面的相關知識。作為交互組的組長&#xff0c;我和組員們在幻爾機器狗的功能開發上有切身的實踐與探索&#xff0c;在張江具身智能大會上&#xff0c;也見識到了前沿的技術和行業的發展現狀…

第十六屆藍橋杯C++B組國賽題解+復盤總結

文章目錄 寫在前面1、新型鎖2、互質藏卡3、數字輪盤4、斐波那契字符串5、項鏈排列6、藍橋星數字7、翻倍8、近似回文字符串9、子串去重10、涂格子 寫在前面 打了三年&#xff0c;第十六屆是我最后一次參加了&#xff0c;終于如愿以償國一啦。 這場的大多題目都補了&#xff0c;…

【TTS】2024-2025年主流開源TTS模型的綜合對比分析

以下是針對2024-2025年主流開源與商用TTS模型的綜合技術選型分析&#xff0c;結合GitHub熱度、功能特性、部署成本及中文支持等核心維度進行對比&#xff0c;并附詳細實踐建議。 一、開源TTS模型對比&#xff08;2024-2025年主流方案&#xff09; 模型名稱開源/廠商克隆支持中…

redis延時雙刪,為什么第一次刪除

Redis延時雙刪策略中第一次刪除的作用 在緩存與數據庫一致性方案中&#xff0c;"延時雙刪"&#xff08;Delayed Double-Delete&#xff09;是一種經典策略&#xff0c;其核心流程如下&#xff1a; 第一次刪除&#xff1a;更新數據庫前&#xff0c;先刪除緩存 更新數…

深度學習1(深度學習和機器學習的區別,神經網絡)

深度學習和機器學習的區別 深度學習和機器學習都是人工智能&#xff08;AI&#xff09;的重要分支&#xff0c;但它們在方法、應用場景和技術細節上有顯著區別。 機器學習通過算法讓計算機從數據中學習規律&#xff0c;并做出預測或決策。核心是特征工程&#xff08;人工提取數…

這才叫窗口查詢!TDEngine官方文檔沒講透的實戰玩法

第1章&#xff1a;你不知道的TDEngine窗口查詢——開局就不簡單 先別急著翻白眼&#xff0c;提到時間窗口查詢&#xff0c;可能你腦子里立馬浮現的就是那些常規套路&#xff1a;GROUP BY time_interval、FIRST()、LAST()&#xff0c;再加上點AVG()和MAX()&#xff0c;一鍋端。…

Day50 預訓練模型+CBAM模塊

目錄 一、resnet結構解析 二、CBAM放置位置的思考 三、針對預訓練模型的訓練策略 a.差異化學習率 b.三階段式解凍與微調 (Progressive Unfreezing) 四、嘗試對vgg16cbam進行微調策略 是否可以對于預訓練模型增加模塊來優化其效果&#xff0c;這里會遇到一個問題&#xff…

快速說一下TDD BDD DDD

基本概念 TDD&#xff08;測試驅動開發&#xff09;、BDD&#xff08;行為驅動開發&#xff09;和 DDD&#xff08;領域驅動設計&#xff09;是軟件開發領域中幾個重要的概念&#xff0c;它們各自有著獨特的側重點與應用場景&#xff0c;以下為你詳細介紹&#xff1a; 測試驅…

淺析基于深度學習算法的英文OCR技術工作原理及其應用場景

在數字化信息飛速發展的當下&#xff0c;大量的文本信息以各種形式存在&#xff0c;從傳統的紙質文檔到電子圖片中的文字內容。如何高效地將這些非結構化的文本轉化為計算機能夠理解和處理的格式&#xff0c;成為了提高信息處理效率的關鍵。英文 OCR&#xff08;Optical Charac…

AI時代SEO關鍵詞策略

內容概要 在人工智能&#xff08;AI&#xff09;驅動的新時代&#xff0c;搜索引擎優化&#xff08;SEO&#xff09;關鍵詞策略正迎來顛覆性變革。本篇文章將系統解析AI技術如何重塑關鍵詞研究、內容優化及流量提升的全過程&#xff0c;幫助企業實現高效可持續的在線曝光。通過…

免費一鍵自動化申請、續期、部署、監控所有 SSL/TLS 證書,ALLinSSL開源免費的 SSL 證書自動化管理平臺

目錄 一、前言二、ALLinSSL 簡介亮點核心功能 三、操作步驟部署安裝授權DNS服務商授權你的主機服務器自動化部署ssl測試自動申請ssl證書 一、前言 SSL證書是每個網站必備的&#xff0c;但是現在的免費的ssl證書有效期是3個月&#xff0c;以后CA/B Forum 調整 SSL 證書最長有效期…

如何高效清理C盤、釋放存儲空間,讓電腦不再卡頓。

以下是針對Windows系統的C盤深度清理全攻略&#xff0c;包含系統級優化和進階操作&#xff0c;可釋放30%-70%的冗余空間&#xff1a; 一、系統自帶工具快速清理&#xff08;5分鐘見效&#xff09; 磁盤清理工具 按WinR → 輸入cleanmgr → 選擇C盤重點勾選&#xff1a; ? Wind…

AI 如何批量提取 Word 表格中的字段數據到 Excel 中?

在日常工作中&#xff0c;我們經常會接觸到大量 Word 表格——學生登記表、客戶信息表、報名信息表……這些表格數據往往格式不一&#xff0c;但有一個共同的需求&#xff1a; 從中提取出“字段-值”結構&#xff0c;統一導入 Excel&#xff0c;方便后續分析處理。 傳統手工操作…

github代碼中遇到的問題-解決方案

下面內容介紹的是我個人在復現github代碼遇到的一些問題&#xff0c;如果也可以幫到你&#xff0c;請點個關注吧~ 1.我的項目位置在D盤&#xff0c;但是為什么下面終端的位置在E盤 -》cd /d D:\Users\xxxx&#xff08;后面的xxxx是你具體的文檔位置&#xff09; 2.怎么知道我…