Go 定时器:如何避免潜在的内存泄漏陷阱

news2024/11/17 3:32:45

在这里插入图片描述

这篇文章将探讨的是 Go 中如何高效使用 timer,特别是与select 一起使用时,如何防止潜在的内存泄漏问题。

引出问题

先看一个例子,我们在 Go 中的 select 使用定时器,实现为消息监听加上超时能力。

核心代码,如下所示:

func main() {
  ch := make(chan int)
  // 启动一个goroutine
  go func() {
    for {
      select {
      case num := <-ch:
        fmt.Println("获取到的数字是", num)
      case <-time.After(2 * time.Second):
        fmt.Println("时间到了!!!")
      }
    }
  }()
  for i := 0; i < 5; i++ {
    ch <- i
    time.Sleep(1 * time.Second)
  }
}

在这个例子中,select 语句用于监听 channel 消息和超时。然而,我要关注的重点是 timer 的行为。它是不是能达到我们预期的目标呢?为消息监听加上超时效果呢?

检查定时器行为

如果运行这段代码,将会发现,如果 timer 设置为 2 秒,主循环设置 1 秒的延迟时间,timer 不会触发。

如下是程序的运行输出:

获取到的数字是 0
获取到的数字是 1
获取到的数字是 2
获取到的数字是 3
获取到的数字是 4

这是因为每次循环,time.After 创建都会返回一个新的定时器,产生的后果就是,每次多会重置 select 调用的时间。

相反,如果将定时器的超时设置为 1 秒,将主循环的time.Sleep设置为 2 秒,就能触发定时器,输出 “时间到了!!!”。这证明了这个定时器是有效运行的。

潜在的内存泄漏

Go标准库文档提到,每次调用time.After都会创建一个新的定时器。然而,我们需要认真考虑一个重要问题。

来自官方文档引用:

The underlying Timer is not recovered by the garbage collector until the timer fires.

如果这些 timer 没有达到设定时间,就不会被 GC。这会导致内存泄漏。毫无疑问,如果在常驻程序中频繁使用 timer 的,内存泄漏将会日积月累。

最佳实践

要高效地管理资源并避免 timer 的内存泄漏,建议使用 time.NewTimer 和 timer.Reset 组合。这种方法允许重复使用一个定时器,减少资源消耗和潜在的内存泄漏风险。

例如,如下是使用 time.NewTimer 改进的代码示例:

// 为定时器定义持续时间。
idleDuration := 5 * time.Minute
// 使用指定的持续时间创建新的定时器。
idleDelay := time.NewTimer(idleDuration)
// 确保定时器适当地停止以避免资源泄漏。
defer idleDelay.Stop()
// 进入循环以处理传入的消息或基于时间的事件。
for {
  // 在每次循环迭代开始时重置定时器到指定的持续时间。
  idleDelay.Reset(idleDuration)
  
  // 使用select等待多个通道操作。
  select {
  // 处理传入消息的情况。
  case s, ok := <-in:
    // 检查通道是否关闭。如果是,退出循环。
    if !ok {
      return
    }
    // 处理接收到的消息`s`。
    // 在这里添加相关代码来处理消息。
  // 处理定时器超时的情况。
  case <-idleDelay.C:
    // 增加空闲计数器或处理超时事件。
    // 这通常是您会在这里添加代码来处理超时情况的地方。
    idleCounter.Inc()
  // 处理取消或上下文过期的情况。
  case <-ctx.Done():
    // 如果上下文已完成,则退出循环。
    return
  }
}

流程如下所示:

这里例子中演示了 Go 语言中如何正确使用和管理 timer。通过遵循 Go 标准库的建议将能产出更高效和可靠的程序。

结论

本文通过一个代码案例演示了 GO 中 timer.After 可能产生的潜在内存泄漏问题。通过使用官方推荐的方案,利用重置定时器时间实现 Timer 的重复利用,避免了潜在的内存泄漏问题。

博文地址:Go 定时器:如何避免潜在的内存泄漏陷阱

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

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

相关文章

java安装,从java1.8升级到java11.0,java,javac,javaw,javaws,jdk,jre

最近在学习 PyFlink&#xff0c;需要安装Java11环境&#xff0c;但是本机已经安装了java1.8&#xff0c;在升级的过程中遇到了一些问题&#xff0c;在这里记录一下。 windows下安装JDK11 下载JDK11&#xff1a;https://www.oracle.com/java/technologies/downloads/#java11-w…

MyBatis入门基础篇

MyBatis基础篇 MyBatis是一款优秀的特久层框架&#xff0c;用于简化JDBC开发。其是Apache的一个开源项目iBatis,2010年这个项目由apache software foundation迁移到了google code,并且改名为MyBatis。2013年11月迁移到Github。由于MyBatis中的大部分API参数与数据库事务息息相…

详细介绍 Go 中如何实现 bitset

文章目录 bitset 结构元素位置代码实现构造函数BitSet 的方法基础方法containsclearadd 集合方法computeSize方法定义intersectuniondifference 遍历集合的元素总结 最近尝试在 B 站录些小视频&#xff0c;我的 B 站主页。录视频当是为了彻底搞懂某个知识点的最后一步吧&#x…

【C++】stack、queue的使用及模拟实现

目录 一、stack1.1 stack的使用1.2 stack的模拟实现 二、queue2.1 queue的使用2.2 queue的模拟实现 一、stack 1.1 stack的使用 stack是一种容器适配器&#xff0c;它的特点是后进先出&#xff0c;只能在容器的一端进行插入和删除操作。 stack的使用很简单&#xff0c;主要有…

代码随想录算法训练营31期day4,力扣24+19+02.07+142

24&#xff0c;动指针 class Solution { public:ListNode* swapPairs(ListNode* head) {//建立虚拟头结点auto dummynew ListNode(-1);dummy->nexthead;for(auto pdummy;p->next&&p->next->next;){auto ap->next;auto ba->next;p->nextb;a->n…

图像旋转角度计算并旋转

#!/usr/bin/python3 # -*- coding: utf-8 -*- import cv2 import numpy as np import timedef Rotate(img, angle0.0,fill0):"""旋转:param img:待旋转图像:param angle: 旋转角度:param fill&#xff1a;填充方式&#xff0c;默认0黑色填充:return: img: 旋转后…

【保驾护航】HarmonyOS应用开发者基础认证-题库

通过系统化的课程学习&#xff0c;熟练掌握DevEco Studio&#xff0c;ArkTS&#xff0c;ArkUI&#xff0c;预览器&#xff0c;模拟器&#xff0c;SDK等HarmonyOS应用开发的关键概念&#xff0c;具备基础的应用开发能力。 考试说明 1、考试需实名认证&#xff0c;请在考前于个…

林浩然的政治学奇幻漂流——幽默诙谐解读马基雅维利

林浩然的政治学奇幻漂流——幽默诙谐解读马基雅维利 Lin Haoran’s Whimsical Exploration of Machiavelli’s Political World 在一个阳光明媚的周末&#xff0c;我们的主人公林浩然同学决定穿越历史长河&#xff0c;踏上一场充满智识与笑声的探索之旅&#xff0c;目的地是文艺…

NineData和泽拓数据库产品Klustron完成产品兼容互认证

近日&#xff0c;云原生智能数据管理平台NineData和泽拓昆仑分布式数据库产品Klustron完成产品兼容互认证。经过严格的联合测试&#xff0c;双方软件完全相互兼容、功能完善、整体运行稳定且性能表现优异。 本次玖章算术与泽拓科技的携力合作&#xff0c;在双方共同的努力下&a…

nextjs中beforePopState使用

在某些情况下&#xff0c;希望监听popstate并在路由器对其进行操作之前执行某些操作。可以使用beforePopState。 在Next.js中&#xff0c;beforePopState是一个可选的生命周期函数&#xff0c;用于在浏览器的历史记录发生更改之前执行一些操作。具体来说&#xff0c;beforePopS…

DP读书:在常工院的2023年度总结

DarrenPig的年度总结 这是最好的时代&#xff0c;这是最坏的时代。——狄更斯 这是最好的时代&#xff0c;这是最坏的时代。——狄更斯 这是最好的时代&#xff0c;这是最坏的时代。——狄更斯 一、2023我的感受 不就是2023吗&#xff0c;不就是一年的经历吗&#xff0c;大家…

18 python快速上手

面向对象进阶 面向对象进阶1.成员1.1 变量易错点 & 面试题 1.2 方法1.3 属性 2.成员修饰符3.对象嵌套4.特殊成员总结 各位小伙伴想要博客相关资料的话关注公众号&#xff1a;chuanyeTry即可领取相关资料&#xff01; 面向对象进阶 目标&#xff1a;掌握面向对象进阶相关知识…

【JavaEE】网络编程 TCP/UDP

作者主页&#xff1a;paper jie_博客 本文作者&#xff1a;大家好&#xff0c;我是paper jie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 本文于《JavaEE》专栏&#xff0c;本专栏是针对于大学生&#xff0c;编程小白精心打造的。笔者用重金(时间和精力)打造&…

WorkPlus移动应用管理平台,助力企业实现高效移动办公

在移动办公成为当今工作方式的主流趋势下&#xff0c;管理和运营企业移动应用成为了提高工作效率和数据安全的重要环节。而移动应用管理平台作为实现移动办公高效管理的关键工具&#xff0c;WorkPlus以其领先的性能和全面的功能&#xff0c;助力企业实现高效移动办公。 为何选…

【医学图像数据增强】切割-拼接(CS-DA)

切割-拼接CS-DA CS-DA 核心思想自然图像和医学图像之间的关键差异CS-DA 步骤确定增强后的数据数量 代码复现 CS-DA 核心思想 论文链接&#xff1a;https://arxiv.org/ftp/arxiv/papers/2210/2210.09099.pdf 大多数用于医学分割的数据增强技术最初是在自然图像上开发的&#x…

【Docker】Kubernetes 命令行 kubectl(kubectl 使用)

作者主页&#xff1a; 正函数的个人主页 文章收录专栏&#xff1a; Docker 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01; kubectl 使用 kubectl 是 Kubernetes 自带的客户端&#xff0c;可以用它来直接操作 Kubernetes。 使用格式有两种&#xff1a; kubectl […

C#hybridCLR热更新方案初探

前言 暂时处于初步研究状态&#xff0c;目前的框架使用还是尚少&#xff0c;本篇文章旨在同步给大家大概的使用流程和使用心得&#xff0c;在初步建立新项目时可以适当考虑。 介绍 热更新 与强制更新相对应&#xff0c;移动平台上App的可执行程序没有发生变化&#xff0c;仅…

免费畅享,打破写作瓶颈:星火写作助手覆盖全面,助你轻松创作

啰嗦几句 最近年终岁末&#xff0c;公司的各种文案各种总结&#xff0c;写得人是头晕脑胀&#xff0c;所以好多小伙伴最近在求智能写作的软件&#xff0c;最好是ChatGPT。 ChatGPT是国外产品&#xff0c;在国内并不能访问。而就智能写作来说&#xff0c;我们何必舍近求远呢&am…

flutter极光推送配置厂商通道(华为)笔记--进行中

一、基础集成按照下面官方文档进行 厂商通道相关参数申请教程 集成厂商 集成指南 官方文档&#xff1a;厂商通道回执配置指南 注意&#xff1a;不同厂商对app上架的要求不同&#xff0c;华为、荣耀 对app上架没有硬性要求 遇到问题 1、引入apply plugin: com.huawei.agconn…