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

网站建设的 关键词怎样可以提升自己的网站

网站建设的 关键词,怎样可以提升自己的网站,彭水网站建设,立方米网站go语言内存泄漏 子字符串导致的内存泄漏 使用自动垃圾回收的语言进行编程时,通常我们无需担心内存泄漏的问题,因为运行时会定期回收未使用的内存。但是如果你以为这样就完事大吉了,哪里就大错特措了。 因为,虽然go中并未对字符串…

go语言内存泄漏

在这里插入图片描述

子字符串导致的内存泄漏

使用自动垃圾回收的语言进行编程时,通常我们无需担心内存泄漏的问题,因为运行时会定期回收未使用的内存。但是如果你以为这样就完事大吉了,哪里就大错特措了。

因为,虽然go中并未对字符串时候共享底层内存块进行规定,但go语言编译器/运行时默认情况下允许字符串共享底层内存块,直到原先的字符串指向的内存被修改才会进行写时复制,这是一个很好的设计,既能节省内存,又能节省CPU资源,但有时也会导致"内存泄漏"。

例如如下代码,一旦调用demo就会导致将近1M内存的泄漏,因为s0只使用了50字节,但是会导致1M的内存一直无法被回收,这些内存会一直持续到下次s0被修改的时候才会被释放掉。

var s0 string // a package-level variable// A demo purpose function.
func f(s1 string) {s0 = s1[:50]// Now, s0 shares the same underlying memory block// with s1. Although s1 is not alive now, but s0// is still alive, so the memory block they share// couldn't be collected, though there are only 50// bytes used in the block and all other bytes in// the block become unavailable.
}func demo() {s := createStringWithLengthOnHeap(1 << 20) // 1M bytesf(s)
}

为了避免这种内存泄漏,我们可以使用[]byte来替代原先的1M大小的内存,不过这样会有两次50字节的内存重复

func f(s1 string) {s0 = string([]byte(s1[:50]))
}

当然我们也可以利用go编译器的优化来避免不必要的重复,只需要浪费一个字节内存就行

func f(s1 string) {s0 = (" " + s1[:50])[1:]
}

上述方法的缺点是编译器优化以后可能会失效,并且其他编译器可能无法提供该优化

避免此类内存泄漏的第三种方法是利用 Go 1.10 以来支持的 strings.Builder

import "strings"func f(s1 string) {var b strings.Builderb.Grow(50)b.WriteString(s1[:50])s0 = b.String()
}

从 Go 1.18 开始, strings 标准库包中新增了 Clone 函数,这成为了完成这项工作的最佳方式。

子切片导致的内存泄漏

同样场景下,切片也会导致内存的浪费

与子字符串类似,子切片也可能导致某种内存泄漏。在下面的代码中,调用 g 函数后,保存 s1 元素的内存块所占用的大部分内存将会丢失(如果没有其他值引用该内存块)。

var s0 []intfunc g(s1 []int) {// Assume the length of s1 is much larger than 30.s0 = s1[len(s1)-30:]
}

如果我们想避免这种内存泄漏,我们必须复制 s0 的 30 个元素,这样 s0 的活跃性就不会阻止收集承载 s1 元素的内存块。

func g(s1 []int) {s0 = make([]int, 30)copy(s0, s1[len(s1)-30:])// Now, the memory block hosting the elements// of s1 can be collected if no other values// are referencing the memory block.
}

未重置子切片指针导致的内存泄漏

在下面的代码中,调用 h 函数后,为切片 s 的第一个和最后一个元素分配的内存块将丢失。

func h() []*int {s := []*int{new(int), new(int), new(int), new(int)}// do something with s ...// 返回一个从1开始,不能到索引3的新切片, 也就是 s[1], s[2]return s[1:3:3]
}

只要返回的切片仍然有效,它就会阻止收集 s 的任何元素,从而阻止收集为 s 的第一个和最后一个元素引用的两个 int 值分配的两个内存块。

如果我们想避免这种内存泄漏,我们必须重置丢失元素中存储的指针。

func h() []*int {s := []*int{new(int), new(int), new(int), new(int)}// do something with s ...// Reset pointer values.s[0], s[len(s)-1] = nil, nilreturn s[1:3:3]
}

挂起Goroutine导致的内存泄漏

有时,Go 程序中的某些 goroutine 可能会永远处于阻塞状态。这样的 goroutine 被称为挂起的 goroutine。Go 运行时不会终止挂起的 goroutine,因此为挂起的 goroutine 分配的资源(以及它们引用的内存块)永远不会被垃圾回收。

Go 运行时不会杀死挂起的 Goroutine 有两个原因。一是 Go 运行时有时很难判断一个阻塞的 Goroutine 是否会被永久阻塞。二是我们有时会故意让 Goroutine 挂起。例如,有时我们可能会让 Go 程序的主 Goroutine 挂起,以避免程序退出。

如果不停止time.Ticker也会导致内存泄漏

time.Timer 值不再使用时,它会在一段时间后被垃圾回收。但 time.Ticker 值则不然。我们应该在 time.Ticker 值不再使用时停止它。

不正确地使用终结器会导致真正的内存泄漏

为属于循环引用组的成员值设置终结器(finalizer)可能会阻止为该循环引用组分配的所有内存块被回收。这是真正的内存泄漏,不是某种假象。

例如,在调用并退出以下函数后,分配给 xy 的内存块不能保证在未来的垃圾收集中被收集。

func memoryLeaking() {type T struct {v [1<<20]intt *T}var finalizer = func(t *T) {fmt.Println("finalizer called")}var x, y T// The SetFinalizer call makes x escape to heap.runtime.SetFinalizer(&x, finalizer)// The following line forms a cyclic reference// group with two members, x and y.// This causes x and y are not collectable.x.t, y.t = &y, &x // y also escapes to heap.
}

因此,请避免为循环引用组中的值设置终结器。

延迟函数调用导致的某种资源泄漏

非常大的延迟调用堆栈也可能会消耗大量内存,并且如果某些调用延迟太多,某些资源可能无法及时释放。

例如,如果在调用以下函数时需要处理许多文件,那么在函数退出之前将有大量文件处理程序无法释放。

func writeManyFiles(files []File) error {for _, file := range files {f, err := os.Open(file.path)if err != nil {return err}defer f.Close()_, err = f.WriteString(file.content)if err != nil {return err}err = f.Sync()if err != nil {return err}}return nil
}

对于这种情况,我们可以使用匿名函数来封装延迟调用,以便延迟函数调用能够更早地执行。例如,上面的函数可以重写并改进为

func writeManyFiles(files []File) error {for _, file := range files {if err := func() error {f, err := os.Open(file.path)if err != nil {return err}// The close method will be called at// the end of the current loop step.defer f.Close()_, err = f.WriteString(file.content)if err != nil {return err}return f.Sync()}(); err != nil {return err}}return nil
}

当然不要犯以下错误,需要有些同学将需要延时调用的函数字节省略,导致资源泄漏

_, err := os.Open(file.path)

如果是http请求,还会导致服务端挤压大量的连接无法释放


文章转载自:

http://ZlHWKd7O.yxwnn.cn
http://FPGC1rIn.yxwnn.cn
http://RrLR0ijD.yxwnn.cn
http://08FtV7gs.yxwnn.cn
http://lN5PpfOg.yxwnn.cn
http://HBjKXXMU.yxwnn.cn
http://xnutgHMV.yxwnn.cn
http://xyhj76uO.yxwnn.cn
http://jpJSB6gA.yxwnn.cn
http://qGh2V3c1.yxwnn.cn
http://tSsNZdq0.yxwnn.cn
http://JdgkU6Zq.yxwnn.cn
http://iiF9KOMM.yxwnn.cn
http://jkvidEhw.yxwnn.cn
http://j4K70675.yxwnn.cn
http://7c5ozZVe.yxwnn.cn
http://E2OOhXHn.yxwnn.cn
http://fgJlP72K.yxwnn.cn
http://L5idXR6k.yxwnn.cn
http://2ymr6g9H.yxwnn.cn
http://JF98U64O.yxwnn.cn
http://FyoAN9Po.yxwnn.cn
http://dOzCMmw6.yxwnn.cn
http://ASvl5xjJ.yxwnn.cn
http://YgdrEALd.yxwnn.cn
http://QWTTThzp.yxwnn.cn
http://vl8tieC9.yxwnn.cn
http://5JnGRTM1.yxwnn.cn
http://PwDR3pUv.yxwnn.cn
http://YP6ZQWCc.yxwnn.cn
http://www.dtcms.com/wzjs/707794.html

相关文章:

  • 仙桃企业网站建设wordpress优雅的暂停
  • 网站推广经理招聘vue开发自适应网站
  • 婚纱网站手机网站宁波市做网站
  • 爱站工具维护为耐克做品牌推广的网站
  • 团购网站 设计方案wordpress怎么批量移动分类
  • 免费招聘网站平台有哪些seo快速排名软件网址
  • 成品网站源码免费分享鹤壁网站建设鹤壁
  • 苏州诗华洛网站建设开发工具控件属性怎么打开
  • 网站留言功能搜搜网站提交入口
  • 沈阳酒店企业网站制作公司行业门户网站制作
  • 高端品牌网站建设注意事项全国设计网站公司网站
  • 自己的网站怎么赚钱上海网站建设网站优化app
  • 青岛网站建设有限公司wordpress没有仪表盘
  • 资源网站排名优化seo的物app
  • 网站文章百度不收录网站建设是属现代服务吗
  • 中国最大的家装网站网站建设的步骤及方法
  • 网站怎么添加后台iis 网站301重定向
  • 余姚网站建设企业沈阳做网站制作的公司
  • 宁德网站开发有没有免费的网站空间
  • 网站建立的重要性专业做书画推广的网站
  • wordpress网站内容地方网站怎么做挣钱
  • 特效相册网站源码上海做网站优化哪家好
  • 在手机上创建网站吗wordpress调用标签代码在线
  • 织梦网站防黑怎么做做网站做系统一样么
  • 如何用vc做网站基于iview的网站开发模板
  • 创建一个网站的项目体现项目完成速度因素的专门发布采购信息的网站
  • 做网站在哪买域名搬瓦工暗转wordpress
  • 徐州市贾汪区建设局网站设计网站多少钱
  • 网站规划与设计大作业郑州旅游网站建设
  • 乐成高端网站建设国外网站问题