GO资源泄漏

1、检查Cmd对象是否释放资源。

-

Java 代码

1cmd := exec.Command("sleep""5")
2err := cmd.Start()
3if err != nil {
4    log.Fatal(err)
5}
6log.Printf("Waiting for command to finish...")
7err = cmd.Wait()
8log.Printf("Command finished with error: %v", err)

 

Start starts the specified command but does not wait for it to complete.

The Wait method will return the exit code and release associated resources once the command exits.

2、检查Process对象是否释放资源。

 

-

Java 代码

01func main() {
02    attr := &os.ProcAttr{
03        Files: []*os.File{os.Stdin, os.Stdout, os.Stderr}, //其他变量如果不清楚可以不设定
04    }
05    p, err := os.StartProcess("/usr/bin/vim", []string{"/usr/bin/vim""tmp.txt"}, attr) //vim 打开tmp.txt文件
06    if err != nil {
07        fmt.Println(err)
08    }
09    fmt.Println(p)                 
10    pro, _ := os.FindProcess(p.Pid) //查找进程
11    fmt.Println(pro)            
12 
13    err = p.Kill()      //杀死进程但不释放进程相关资源
14    fmt.Println(err)
15 
16    err = p.Release()    // 释放进程相关资源,因为资源释放凋之后进程p就不能进行任何操作,此后进程P的任何操作都会被报错</span>
17    fmt.Println(err)
18}

3、检查Reponse对象是否释放资源。

-

Java 代码

1错误案例:for {
2    _, err = http.Post(url, "", nil) // 此处返回的reponse对象被忽略掉,应调用resp.Body.Close()释放资源
3    if err != nil {
4        fmt.Println(err)
5    }
6    time.Sleep(Interval)
7}

4、检查Ticker对象是否正释放资源

-

Java 代码

01func main() {
02    ticker := time.NewTicker(time.Second)
03    defer ticker.Stop() // 如果未调用该方法,会造成ticker资源无法释放
04    done := make(chan bool)
05    go func() {
06        time.Sleep(10 * time.Second)
07        done <- true
08    }()
09    for {
10        select {
11        case <-done:
12            fmt.Println("Done!")
13            return
14        case t := <-ticker.C:
15            fmt.Println("Current time: ", t)
16        }
17    }
18}

5、检查文件对象是否释放资源 

-

Java 代码

1h, err := os.Open("/path/to/file.txt")
2if err != nil {
3   // ......
4    return// 此处直接返回,会导致句柄泄漏
5}
6defer fh.Close()

-

Java 代码

01for {
02     // 从管道接收消息并处理...
03 
04     fOut, err := os.OpenFile(fileTempPath, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0644)
05     defer fOut.Close() // defer只有在函数退出时调用,而且此处调用多次,defer栈会越来越大    
06if err != nil {
07         gsflog.Error("fail to creat file:", fileTempPath, err)
08         continue
09      }
10      if errPerm := os.Chmod(fileTempPath, 0600); errPerm != nil {
11         gsflog.Error("change bill path perm fail:", errPerm)
12      }
13      fOut.WriteString(billStr)
14      billNum++
15   }

 

 

6、goroutine资源泄漏

一般是由于channel的错误使用,IO操作堵塞或者Http请求超时,没有超时机制,导致

 

package main

import (  
    "fmt"  
    "math/rand"  
    "runtime"  
    "time"  
)

func query() int {  
    n := rand.Intn(100)  
    time.Sleep(time.Duration(n) * time.Millisecond)  
    return n  
}

func queryAll() int {  
    ch := make(chan int)  
    go func() { ch <- query() }()  
    go func() { ch <- query() }()  
    go func() { ch <- query() }()  
    return <-ch  // channel没有接收完,直接退出,导致另外两个channel无法写入,goroutine持续泄漏
}

func main() {  
    for i := 0; i < 4; i++ {  
        queryAll()  
        fmt.Printf("#goroutines: %d", runtime.NumGoroutine())  
    }  
}

 

 

C语言资源泄漏:

检视点:
1、所有的分支路径上是否将分配的内存进行了释放
2、所有的分支路径上是否释放应该释放的资源
3、宏里面有return语句,可能引起前面申请的内存无法释放
4、多个内存申请的内存指针写在一起,异常处理可能导致前面申请内存无法释放。
5、在一个函数申请的资源,传递在外部处理。
6、结构体内部指针指向的内存需释放。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值