当前位置: 首页 > wzjs >正文

注册网站填写不了地区WordPress 知更鸟主题

注册网站填写不了地区,WordPress 知更鸟主题,阎良建设局 网站,description 网站描述(上图用 go tool pprof 工具分析生成) 这种会造成内存泄露 因为每次for都会新建一个time对象,只有到期后会被回收。 解决方法:用time.NewTimer与time.Reset每次重新激活定时器 背景 我先贴一下会发生内存泄漏的代码段&#xff0c…

在这里插入图片描述
(上图用 go tool pprof 工具分析生成)
这种会造成内存泄露 因为每次for都会新建一个time对象,只有到期后会被回收。
解决方法:用time.NewTimer与time.Reset每次重新激活定时器

背景
我先贴一下会发生内存泄漏的代码段,根据代码可以更好的进行讲解:

func (b *BrokerImpl) broadcast(msg interface{}, subscribers []chan interface{}) {count := len(subscribers)concurrency := 1switch {case count > 1000:concurrency = 3case count > 100:concurrency = 2default:concurrency = 1}pub := func(start int) {for j := start; j < count; j += concurrency {select {case subscribers[j] <- msg:case <-time.After(time.Millisecond * 5):case <-b.exit:return}}}for i := 0; i < concurrency; i++ {go pub(i)}
}

看了这段代码,你知道是哪里发生内存泄漏了嘛?我先来告诉大家,这里time.After(time.Millisecond * 5)会发生内存泄漏,具体原因嘛别着急,我们一步步分析。

我们来写一段代码进行验证,先看代码吧:

package mainimport ("fmt""net/http"_ "net/http/pprof""time"
)/**time.After oom 验证demo*/
func main()  {ch := make(chan string,100)go func() {for  {ch <- "asong"}}()go func() {// 开启pprof,监听请求ip := "127.0.0.1:6060"if err := http.ListenAndServe(ip, nil); err != nil {fmt.Printf("start pprof failed on %s\n", ip)}}()for  {select {case <-ch:case <- time.After(time.Minute * 3):}}
}

这段代码我们该怎么验证呢?

看代码估计你们也猜到了,没错就是go tool pprof,可能有些小伙伴不知道这个工具,那我简单介绍一下基本使用,不做详细介绍,更多功能可自行学习。
再介绍pprof之前,我们其实还有一种方法,可以测试此段代码是否发生了内存泄漏,就是使用top命令查看该进程占用cpu情况,输入top命令,我们会看到cpu一直在飙升,这种方法可以确定发生内存泄漏,但是不能确定发生问题的代码在哪部分,所以最好还是使用pprof工具进行分析,他可以确定具体出现问题的代码。

proof 介绍
定位goroutine泄露会使用到pprof,pprof是Go的性能工具,在程序运行过程中,可以记录程序的运行信息,可以是CPU使用情况、内存使用情况、goroutine运行情况等,当需要性能调优或者定位Bug时候,这些记录的信息是相当重要。使用pprof有多种方式,Go已经现成封装好了1个:net/http/pprof,使用简单的几行命令,就可以开启pprof,记录运行信息,并且提供了Web服务,能够通过浏览器和命令行2种方式获取运行数据。
基本使用也很简单,看这段代码:

package mainimport ("fmt""net/http"_ "net/http/pprof"
)func main() {// 开启pprof,监听请求ip := "127.0.0.1:6060"if err := http.ListenAndServe(ip, nil); err != nil {fmt.Printf("start pprof failed on %s\n", ip)}
}

使用还是很简单的吧,这样我们就开启了go tool pprof。下面我们开始实践来说明pprof的使用。
验证流程
首先我们先运行我的测试代码,然后打开我们的终端输入如下命令:

$ go tool pprof -http=:8081 http://localhost:6060/debug/pprof/heap

复制代码
浏览器会自动弹出,看下图:

看这个图,都爆红了,time.Timer导致占用CPU内存飙升,现在找到问题了,下面我们就可以来分析一下了。
原因分析
分析具体原因之前,我们先来了解一下go中两个定时器ticker和timer,因为不知道这两个的使用,确实不知道具体原因。

ticker和timer
Golang中time包有两个定时器,分别为ticker 和 timer。两者都可以实现定时功能,但各自都有自己的使用场景。
我们来看一下他们的区别:

ticker定时器表示每隔一段时间就执行一次,一般可执行多次。
timer定时器表示在一段时间后执行,默认情况下只执行一次,如果想再次执行的话,每次都需要调用 time.Reset()方法,此时效果类似ticker定时器。同时也可以调用stop()方法取消定时器
timer定时器比ticker定时器多一个Reset()方法,两者都有Stop()方法,表示停止定时器,底层都调用了stopTimer()函数。

原因
上面我们了介绍go的两个定时器,现在我们回到我们的问题,我们的代码使用time.After来做超时控制,time.After其实内部调用的就是timer定时器,根据timer定时器的特点,具体原因就很明显了。
这里我们的定时时间设置的是3分钟, 在for循环每次select的时候,都会实例化一个一个新的定时器。该定时器在3分钟后,才会被激活,但是激活后已经跟select无引用关系,被gc给清理掉。这里最关键的一点是在计时器触发之前,垃圾收集器不会回收 Timer,换句话说,被遗弃的time.After定时任务还是在时间堆里面,定时任务未到期之前,是不会被gc清理的,所以这就是会造成内存泄漏的原因。每次循环实例化的新定时器对象需要3分钟才会可能被GC清理掉,如果我们把上面代码中的3分钟改小点,会有所改善,但是仍存在风险,下面我们就使用正确的方法来修复这个bug。
修复bug
使用timer定时器
time.After虽然调用的是timer定时器,但是他没有使用time.Reset() 方法再次激活定时器,所以每一次都是新创建的实例,才会造成的内存泄漏,我们添加上time.Reset每次重新激活定时器,即可完成解决问题。

func (b *BrokerImpl) broadcast(msg interface{}, subscribers []chan interface{}) {count := len(subscribers)concurrency := 1switch {case count > 1000:concurrency = 3case count > 100:concurrency = 2default:concurrency = 1}//采用Timer 而不是使用time.After 原因:time.After会产生内存泄漏 在计时器触发之前,垃圾回收器不会回收Timerpub := func(start int) {idleDuration := 5 * time.MillisecondidleTimeout := time.NewTimer(idleDuration)defer idleTimeout.Stop()for j := start; j < count; j += concurrency {if !idleTimeout.Stop(){select {case <- idleTimeout.C:default:}}idleTimeout.Reset(idleDuration)select {case subscribers[j] <- msg:case <-idleTimeout.C:case <-b.exit:return}}}for i := 0; i < concurrency; i++ {go pub(i)}
}

总结

不知道这篇文章你们看懂了吗?没看懂的可以下载测试代码,自己测试一下,更能加深印象的呦~~~
这篇文章主要介绍了排查问题的思路,go tool pprof这个工具很重要,遇到性能和内存gc问题,都可以使用golang tool pprof来排查分析问题。不会的小伙伴还是要学起来的呀~~~
最后感谢指出问题的那位网友,让我又有所收获,非常感谢,所以说嘛,还是要共同进步的呀,你不会的,并不代表别人不会,虚心使人进步嘛,加油各位小伙伴们~~~

作者:Golang梦工厂
链接:https://juejin.cn/post/6874561727145443335
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


文章转载自:

http://yswxMDhR.knLyL.cn
http://fA5hg3sN.knLyL.cn
http://FjZv3pSP.knLyL.cn
http://IulKBOx5.knLyL.cn
http://So3Edr80.knLyL.cn
http://gxJJqBP0.knLyL.cn
http://OQo9ox4a.knLyL.cn
http://8WRDGO8Q.knLyL.cn
http://SbprGkxs.knLyL.cn
http://giWeNUT9.knLyL.cn
http://wQD5NQHX.knLyL.cn
http://jXcXRe98.knLyL.cn
http://OOIR0hqQ.knLyL.cn
http://pFCHcG1S.knLyL.cn
http://VNIn4aoB.knLyL.cn
http://hJC3IFeH.knLyL.cn
http://liS6xeVP.knLyL.cn
http://Qn9rWdOP.knLyL.cn
http://x5qAC2WD.knLyL.cn
http://GFfFJsqH.knLyL.cn
http://r2dO2t2X.knLyL.cn
http://Cc7TXNYE.knLyL.cn
http://64awvu5W.knLyL.cn
http://btuwTgKe.knLyL.cn
http://IUlHpysS.knLyL.cn
http://ceh5zCNa.knLyL.cn
http://ZHEff9gn.knLyL.cn
http://J10iVw1F.knLyL.cn
http://Sw1SGtmd.knLyL.cn
http://1AO3wu8m.knLyL.cn
http://www.dtcms.com/wzjs/651829.html

相关文章:

  • dz网站收款即时到账怎么做的北京网页制作设计
  • 哪个视频网站做视频赚钱什么是网站app建设
  • 考百度指数 某个关键词在某个行业网站上的淘宝客网站备案
  • 食品类网站模板地方网站域名
  • 电脑网站打不开怎么解决全国文明城市创建工作
  • 如何在各个购物网站之间做差价六安建六安建设网站
  • 南宁软件优化网站首页关键词优化公司
  • apache多网站配置企业网站前台静态模板
  • 销售网站建设公司wordpress 文章 图片 插件
  • 盐城市建设局网站打不开wordpress主题 秀
  • seo诊断工具网站新能源电动汽车哪个牌子的质量好
  • dw做网站教程视频烟台网站建站
  • 唐山手机网站建设百度极速版app下载安装
  • pe管网站建设 中企动力页面设计英文
  • 石家庄模板建站WordPress直接调用头像地址
  • 书店网站建设策划书苏州电商关键词优化
  • 厦门建设局网站工程师评审关于织金县网站建设的论文
  • 网站建设课程感想图片seo优化是什么意思
  • 如何选择网站模板一个空间能否做两个网站
  • 谷歌云 阿里云 做网站怎么建设一个网站赚钱
  • 手机自助建站永久免费linux建立网站
  • 做淘宝客网站服务器深圳市住房和建设局工程交易平台
  • 网站开发工具安卓版阿里巴巴logo高清图
  • 有没有专业做二维码连接网站在宁波seo网页怎么优化
  • 网站用户访问统计网页设计公司理念
  • 织梦网站导航固定seo计费系统登录
  • 简单网站后台企业网站一定要从建立网站开始
  • 厦门网站建设团队软件汇
  • 站长网站素材WordPress登录页提示
  • 如何做一网站首页网站域名解绑