golang逃逸分析

1.1 逃逸分析是什么

逃逸分析是指編譯器在執行靜態代碼分析后,對內存管理進行的優化和簡化。

在編譯原理中,分析指針動態范圍的方法被稱為逃逸分析。通俗來講,當一個對象的指針被多個方法或線程引用時,則稱這個指針發生了逃逸。逃逸分析決定一個變量是分配在堆上還是分配在棧上。

1.2 逃逸分析有什么作用

逃逸分析把變量合理地分配到它該去的地方,“找準自己的位置”。既是使用 new 函數申請到的內存,如果編譯器發現這塊內存在退出函數后就沒有使用了,那就分配到棧上,畢竟棧上的內存分配比堆上快很多;反之,既是表面上只是一個普通的變量,但是經過編譯器的逃逸分析后發現,在函數之外還有其他的地方在引用,那就分配到堆上。真正做到 “按需分配”。

如果變量都分配到堆上,堆不像棧可以自動清理。就會引起 Go 頻繁地進行垃圾回收,而垃圾回收會占用比較大的系統開銷。

堆和棧相比,堆適合不可預知大小的內存分配。但是為此付出的代價是分配速度較慢,而且會形成內存碎片;棧內存分配則非常快。棧分配內存只需通過 PUSH 指令,并且會被自動釋放;而堆分配首先需要去找到一塊大小合適的內存塊,之后要通過垃圾回收才能釋放。

通過逃逸分析,可以盡量把那些不需要分配到堆上的變量直接分配到棧上,堆上的變量變少了,會減輕堆內存分配的開銷,同時也會減少垃圾回收(Garbage Collction,GC)的壓力,提高程序運行速度。

1.3 逃逸分析是怎么完成的

Go 語言逃逸分析最基本的原則是:如果一個函數返回對一個變量的引用,那么這個變量就會發生逃逸。

編譯器會分析代碼的特征和代碼的生命周期,Go 中的變量只有在編譯器可以證明在函數返回后不再被引用,才分配到棧上,其他情況下都是直接分配到堆上。

Go 語言里沒有一個關鍵字或者函數可以直接讓變量被編譯器分配到堆上。相反,編譯器通過分析代碼來決定將變量分配到何處。

對一個變量取地址,可能會被分配到堆上。但是編譯器進行逃逸分析后,如果考慮到在函數返回后,此變量不會被引用,那么還是可能分配到棧上。簡單來說,編譯器會根據變量是否被外部引用來決定是否逃逸:

如果變量在函數外部沒有被引用,則優先放到棧上。
如果變量在函數外部存在引用,則必定放在堆上。
針對第一條,放到堆上的情形:定義了一個很大的數組,需要申請的內存過大,超過了棧的存儲能力。

1.4 如何確定是否發生逃逸分析

Go 提供了相關的命令,可以查看變量是否發生了逃逸。例子如下:

package  mainimport  "fmt"func  foo() *int {t :=  3return  &t
}func  main() {x :=  foo()fmt.Println(*x)
}

foo 函數返回一個局部變量的指針,使用 main 函數里變量 x 接收它。執行如下命令:

go build -gcflags '-m-l' main.go

其中 -gcflags 參數用于啟用編譯器支持的額外標志。例如, -m 用于輸出編譯器的優化細節(包括使用逃逸分析這種優化),相反可以使用 -N 來關閉編譯器優化;而 -l 則用于禁用 foo 函數的內聯優化,防止逃逸被編譯器通過內聯優化徹底的抹除。得到如下輸出:

### command-line-arguments
src/main.go:7:9: &t escapes to heap
src/main.go:6:7: moved to heap: t
src/main.go:12:14: *x escapes to heap
src/main.go:12:13: main ... argument does not escape

foo 函數里的變量 t 逃逸了,和預想的一致,不解的是為什么 main 函數里的 x 也逃逸了?這是以為有些函數的參數為 interface 類型,比如 fmt.Println(a …interface{}) ,編譯期間很難確定其參數的具體類型,也會發生逃逸。

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

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

相關文章

Meetily:AI會議記錄,開源、免費、好用(本地AI實時轉錄、隱私保護一步到位!)

名人說:博觀而約取,厚積而薄發。——蘇軾《稼說送張琥》 創作者:Code_流蘇(CSDN)(一個喜歡古詩詞和編程的Coder??) 目錄 一、初識Meetily:什么是真正的智能會議助手?1. 核心優勢一覽2. 技術架構揭秘二、實戰體驗:從安裝到使用的完整流程1. 系統要求2. 快速安裝指南Wi…

.NET ORM開發手冊:基于SqlSugar的高效數據訪問全攻略

SqlSuger是一個國產,開源ORM框架,具有高性能,使用方便,功能全面的特點,支持.NET Framework和.NET Core,支持各種關系型數據庫,分布式數據庫,時序數據庫。 官網地址:SqlS…

【論文閱讀】KIMI-VL TECHNICAL REPORT

KIMI-VL TECHNICAL REPORT 原文摘要 核心模型:Kimi-VL 模型架構:基于 MoE 設計,僅激活語言解碼器的 2.8B 參數(Kimi-VL-A3B),在保持高效計算的同時實現高性能。 MoE(Mixture of Experts&#xf…

項目管理學習-CSPM4(2)

1 前言 最近在學習CSPM的課程,部分內容讓我受益匪淺。建議需要提升項目管理能力的同學可以通過以考促學的方式進行學習。下面整理了一部分內容和大家分享。CSPM全稱China Standards Project Management,中文名為項目管理專業人員能力評價等級證書&#…

【Web前端】ECMAScript 6基礎學習

ECMAScript 6 簡介 ECMAScript 和 JavaScript 的關系:前者是后者的規格,后者是前者的一種實現,常場合,這兩個詞是可以互換的。 ECMAScript 6(以下簡稱 ES6)是 JavaScript 語言的標準,在 2015 年 6 月發布…

基于Python的全卷積網絡(FCN)實現路徑損耗預測

以下是一份詳細的基于Python的全卷積網絡(FCN)實現路徑損耗預測的技術文檔。本方案包含理論基礎、數據生成、模型構建、訓練優化及可視化分析,代碼實現約6000字。 基于全卷積網絡的無線信道路徑損耗預測系統 目錄 問題背景與需求分析系統架構設計合成數據生成方法全卷積網絡…

AI數字人一體機和智慧屏方案:開啟智能交互新紀元

在當今這個信息化飛速發展的時代,AI技術正以前所未有的速度改變著我們的生活方式和工作模式。特別是在人機交互領域,AI數字人的出現不僅極大地豐富了用戶體驗,也為各行各業提供了前所未有的創新解決方案。本文將重點介紹由廣州深聲科技有限公…

練習實踐--deepseek的使用環境搭建回顧--火山方舟

快速回顧 有更多第三方可以提供免費的大模型體驗服務,比如硅基流動/火山方舟,通過選擇指定模型,生成模型id和自己的API-KEY這兩個信息,可以在第三方集成ai工具,如cherry studio上使用; 參考來源 來自阮一…

Adminer 連接mssql sqlserver

第一步 docker-compose.yml adminer部分: version: 3.8 services: adminer: image: adminer:latest container_name: adminer restart: unless-stopped volumes: - ./freetds/freetds.conf:/etc/freetds.conf:rw # 確保 :rw 可讀寫 co…

JWT令牌詳解及Java中的使用實戰

JWT令牌詳解及Java中的使用實戰 摘要 本文將深入解析**JWT(JSON Web Token)**的核心概念,通過圖文并茂的方式詳解其工作原理,并手把手教你在Java中實現JWT的生成、驗證與解析。無論你是認證授權新手還是想鞏固知識的老手&#x…

晶圓隱裂檢測提高半導體行業效率

半導體行業是現代制造業的核心基石,被譽為“工業的糧食”,而晶圓是半導體制造的核心基板,其質量直接決定芯片的性能、良率和可靠性。晶圓隱裂檢測是保障半導體良率和可靠性的關鍵環節。 晶圓檢測 通過合理搭配工業相機與光學系統&#xff0c…

Java 的 ReentrantLock

Java中的ReentrantLock是java.util.concurrent.locks包下提供的一個可重入互斥鎖,用于替代synchronized關鍵字實現更靈活的線程同步。以下是其核心特性和使用方法的詳細說明: 核心特性 可重入性 同一個線程可以重復獲取同一個鎖(鎖的持有計數…

達夢數據庫-學習-23-獲取執行計劃的N種方法

目錄 一、環境信息 二、說點什么 三、測試數據生成 四、測試語句 五、獲取執行計劃方法 1、EXPLAIN (1)樣例 (2)優勢 (3)劣勢 2、ET (1)開啟參數 (2&#xff…

20200201工作筆記常用命令要整理

工作筆記常用命令: 1.repo常用命令: repo sync -c -j10 2. 常用adb命令 錯誤: error: device unauthorized. This adbds $ADB_VENDOR_KEYS is not set; try adb kill-server if that seems wrong. Otherwise check for a confirmation dialog on your d…

PET,Prompt Tuning,P Tuning,Lora,Qlora 大模型微調的簡介

概覽 到2025年,雖然PET(Pattern-Exploiting Training)和Prompt Tuning在學術界仍有探討,但在工業和生產環境中它們已基本被LoRA/QLoRA等參數高效微調(PEFT)方法取代 。LoRA因其實現簡單、推理零開銷&#…

9種方法,一鍵美化Python圖表

Matplotlib、Seaborn默認參數不好看,美化需要大量代碼。 本次分享9種方法,一鍵美化圖表,看看那個是你的菜。 1 Matplotlib style sheets Matplotlib內置多類style sheets, 一行代碼使用, plt.style.use(Solarize_Li…

在STM32上配置圖像處理庫

在STM32上配置并使用簡單的圖像濾波庫(以實現均值濾波為例,不依賴復雜的大型圖像處理庫,方便理解和在資源有限的STM32上運行)為例,給出代碼示例,使用STM32CubeIDE開發環境和HAL庫,假設已經初始化好了相關GPIO和DMA(如果有圖像數據傳輸需求),并且圖像數據存儲在一個二…

Android四大組件學習總結

?1. Activity 啟動模式問題? ?面試官?: “我看你項目里用了 SingleTask 模式,能具體說說為什么用它嗎?如果從 Activity A(SingleTask)跳轉到 B(Standard),再返回 A,…

基于SamOutV8的序列生成模型實現與分析

項目概述 本項目實現了基于SamOutV8架構的序列生成模型,核心組件包括MaxStateSuper、FeedForward和DecoderLayer等模塊。通過結合自注意力機制與狀態編碼策略,該模型在處理長序列時表現出良好的性能。 核心組件解析 1. MaxStateSuper(狀態編…

從腦電圖和大腦記錄中學習穩健的深度視覺表征

從腦電圖和大腦記錄中學習穩健的深度視覺表征 印度,印度,印度,印度大腦實驗室,印度 例如,達拉普,克普拉薩德,山,山,新的。ac .在 摘要 解碼人類大腦一直是新機器人科學家…