Goland 内存逃逸问题

内存逃逸是什么?

在go语言中,内存分配存在两个方式:堆分配;栈分配。

栈分配:是在函数调用时为局部变量分配内存,当函数返回时,这些内存会自动释放。

堆分配:通过 new 或者 make 函数动态分配内存,需要手动进行释放或者自动回收机制释放。

内存逃逸是指原先在栈上分配的内存被分配到堆上。这样导致函数结束时不能自动回收,只能通过垃圾回收器回收,对于性能影响较大。

内存逃逸的几种情况

1.返回指针导致内存逃逸

package mainimport "fmt"func createPointer() *int {x := 100 // 局部变量return &x // x 逃逸到堆上
}func main() {p := createPointer()fmt.Println(*p) // 100
}

为什么发生了逃逸?

  • xcreatePointer() 的局部变量,正常情况下函数返回后应该销毁
  • 但是 &x 返回了 x 的地址,导致 x 需要在 main() 继续使用,不能放在栈上,必须逃逸到堆

2.切片或 map 赋值导致逃逸

package mainfunc main() {s := make([]int, 3) // 堆分配m := make(map[int]int) // 堆分配_ = s_ = m
}

为什么发生了逃逸?

  • make([]int, 3) 创建了切片,其底层数组可能存储在堆上(具体取决于大小)
  • make(map[int]int) 创建的 map 结构存储在堆上,因为 map 需要在多个作用域间传递。

3.字符串和 interface{} 赋值导致逃逸

package mainimport "fmt"func printAny(i interface{}) {fmt.Println(i)
}func main() {x := "hello"printAny(x) // x 逃逸到堆
}

为什么发生了逃逸?

  • xstring,但 printAny() 需要 interface{}
  • Go 需要将 x 装箱(boxing),创建 interface{} 类型的值,而 interface{} 可能存储在堆上

4.闭包捕获变量导致逃逸

package mainimport "fmt"func closure() func() int {x := 42return func() int {return x // x 逃逸到堆}
}func main() {f := closure()fmt.Println(f()) // 42
}

为什么发生了逃逸?

  • xclosure() 的局部变量,但被匿名函数 func() int 捕获
  • 由于 func() int 可能在 closure() 结束后仍然被调用,x 必须分配到堆上

如何避免内存逃逸?

避免返回指针

错误情况

// ❌ 发生逃逸
func bad() *int {
    x := 42
    return &x
}

改进(使用值返回,而不是指针) 

func good() int {
    x := 42
    return x // 不逃逸
}

使用参数传递而不是使用闭包

func returnFunction(x int) func() int {
    return func() int { return x }
}

 使用 sync.Pool 复用对象

package main

import (
    "fmt"
    "sync"
)

var pool = sync.Pool{
    New: func() interface{} { return new(int) },
}

func main() {
    p := pool.Get().(*int) // 复用对象,减少堆分配
    *p = 100
    fmt.Println(*p)
    pool.Put(p) // 归还对象
}

 使用 strings.Builder 代替字符串拼接

package main

import (
    "fmt"
    "strings"
)

func main() {
    var sb strings.Builder // 避免字符串逃逸
    sb.WriteString("Hello ")
    sb.WriteString("World")
    fmt.Println(sb.String())
}

总结

逃逸原因例子解决方案
返回指针return &x返回值而不是指针
切片/Mapmake([]int, 3)小数组可用 var arr [3]int
interface{}printAny(x)避免不必要的 interface{}
闭包捕获变量return func() { return x }使用 参数传递 而不是 闭包
字符串拼接s += "hello"strings.Builder

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/69554.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

视觉硬件选型和算法选择(CNN)

基础知识 什么是机械视觉: 机械视觉是一种利用机器代替人眼来进行测量和判断的技术,通过光学系统、图像传感器等设备获取图像,并运用图像处理和分析算法来提取信息,以实现对目标物体的识别、检测、测量和定位等功能。 机械视觉与人类视觉有什…

尝试一下,交互式的三维计算python库,py3d

py3d是一个我开发的三维计算python库,目前不定期在PYPI上发版,可以通过pip直接安装 pip install py3d 开发这个库主要可视化是想把自己在工作中常用的三维方法汇总积累下来,不必每次重新造轮子。其实现成的python库也有很多,例如…

【C++高并发服务器WebServer】-15:poll、epoll详解及实现

本文目录 一、poll二、epoll2.1 相对poll和select的优点2.2 epoll的api2.3 epoll的demo实现2.5 epoll的工作模式 一、poll poll是对select的一个改进,我们先来看看select的缺点。 我们来看看poll的实现。 struct pollfd {int fd; /* 委托内核检测的文件描述符 */s…

深度分析:网站快速收录与网站内容多样性的关系

本文转自:百万收录网 原文链接:https://www.baiwanshoulu.com/87.html 网站快速收录与网站内容多样性之间存在着密切的关系。以下是对这一关系的深度分析: 一、网站内容多样性对快速收录的影响 提升搜索引擎抓取效率: 多样化的…

接入 deepseek 实现AI智能问诊

1. 准备工作 注册 DeepSeek 账号 前往 DeepSeek 官网 注册账号并获取 API Key。 创建 UniApp 项目 使用 HBuilderX 创建一个新的 UniApp 项目(选择 Vue3 或 Vue2 模板)。 安装依赖 如果需要在 UniApp 中使用 HTTP 请求,推荐使用 uni.requ…

PLSQL: 存储过程,用户自定义函数[oracle]

注意: raise notice是高斯的输出语句; DBMS_OUT_PUT.PUT_LINE是oracle的输出语句 存储过程 Stored Procedure 存储过程可以封装数据访问逻辑,使得应用程序可以通过调用存储过程来执行这些逻辑,而不是直接执行SQL语句。这有助于提高代码的可重用性、可…

从零开始玩转Docker:轻松开启容器化之旅

一、什么是 Docker Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。简单来说,Docker 就像是一个超级 “快递箱”&#xff0c…

deepseek+kimi自动生成ppt

打开deepseek官网,输入详细的需求,让他生成个ppt 接着deepseek开始思考生成了 接着复制生成了的内容 打开kimi粘贴刚才deepseek生成的内容 可以一键生成啦,下载编辑使用吧

关于预训练后训练、LLM和视频大模型相关学习记录

Pre-training与Post-training 预训练主要是“模仿”,而后训练则是“创造” 预训练对数据质量的要求不高,而后训练对数据质量的要求较高 预训练:模型通过预测海量互联网文本数据中的下一个 token,学习语言的通用规律,得…

单张照片可生成写实3D头部模型!Adobe提出FaceLift,从单一的人脸图像中重建出360度的头部模型。

FaceLift是Adobe和加州大学默塞德分校推出的单图像到3D头部模型的转换技术,能从单一的人脸图像中重建出360度的头部模型。FaceLift基于两阶段的流程实现:基于扩散的多视图生成模型从单张人脸图像生成一致的侧面和背面视图;生成的视图被输入到GS-LRM重建器中,产出详细的3D高斯表…

一文了解服务端渲染及前端在服务端渲染上的应用

文章目录 服务端和 vs 客户端概念应用场景需求考量优缺点 服务端渲染应用Nuxt.js 介绍概念特点应用场景 Nuxt 与 Vue 3 的综合应用支持情况开发步骤1. 项目初始化2. 使用组合式 API3. 集成 Vue 3 插件4. 静态站点生成和服务器端渲染 优势 Next.js 介绍概念特点应用场景 Next 与…

机器学习:朴素贝叶斯分类器

贝叶斯决策论是概率框架下实施决策的基本方法,对分类任务来说,在所有相关概率都已知的理想情形下,贝叶斯决策论考虑如何基于这些概率和误判损失来选择最优的类别标记。 贝叶斯定理是贝叶斯决策论的基础,描述了如何根据新的证据更新先验概率,贝叶斯定理&…

差速驱动机器人MPC算法实现-C++

差速驱动机器人,其运动学模型需要考虑线速度和角速度。MPC(模型预测控制)需要建立预测模型,并在每个控制周期内求解优化问题。 差速驱动机器人的运动学方程通常包括位置(x, y)和航向角θ,线速度…

5 计算机网络

5 计算机网络 5.1 OSI/RM七层模型 5.2 TCP/IP协议簇 5.2.1:常见协议基础 一、 TCP是可靠的,效率低的; 1.HTTP协议端口默认80,HTTPSSL之后成为HTTPS协议默认端口443。 2.对于0~1023一般是默认的公共端口不需要注册,1024以后的则需…

mysql8 从C++源码角度看sql生成抽象语法树

在 MySQL 8 的 C 源码中,SQL 语句的解析过程涉及多个步骤,包括词法分析、语法分析和抽象语法树(AST)的生成。以下是详细的解析过程和相关组件的描述: 1. 词法分析器(Lexer) MySQL 使用一个称为…

excel合并表格

上一章说到excel拆分表格,可以按一列的不重复数据自动拆分成多个表格。这个功能主要适用于有多个下级机构的部门分发表格使用。表格分发完成,下级单位修改后,上传到我们这里。我们还得把这些表格合并成一个表。如果利用复制粘性,工…

区块链100问之加密算法

区块链100问之加密算法 文章目录 区块链100问之加密算法哈希算法是什么?有什么特征?哈希碰撞是什么?雪崩效应呢?如何解决?哈希算法的作用?对称加密和非对称加密有什么区别?为什么会引入非对称加密&#xf…

模型压缩中的四大核心技术 —— 量化、剪枝、知识蒸馏和二值化

一、量化 (Quantization) 量化的目标在于将原始以 32 位浮点数表示的模型参数和中间激活,转换为低精度(如 FP16、INT8、甚至更低位宽)的数值表示,从而在减少模型存储占用和内存带宽的同时,加速推理运算,特别适用于移动、嵌入式和边缘计算场景。 1.1 概念与目标 基本思想…

【LLM】o1/R1系列LLM数据篇

关于思维链推理的10开源数据集: 目前开源的数据主要有如下: 1、Magpie-Reasoning-V2数据集,其中包含DeepSeek-R1生成的250K思路链推理样本,这些示例涵盖了数学推理、编码和一般问题解决等各种任务。https://huggingface.co/datas…

elasticsearch实战应用从入门到高效使用java集成es快速上手

Elasticsearch 因其出色的性能、可扩展性和易用性,成为了处理大规模数据和构建搜索引擎的首选工具。本文将通过一个实际案例,详细讲解如何在 Spring Boot 项目中集成 Elasticsearch,进行数据索引、搜索、聚合分析等操作。 一、Elasticsearch 简介 Elasticsearch 是一个基于…