Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UTP causes memory leak #392

Closed
ucwong opened this issue Apr 3, 2020 · 38 comments
Closed

UTP causes memory leak #392

ucwong opened this issue Apr 3, 2020 · 38 comments

Comments

@ucwong
Copy link
Contributor

ucwong commented Apr 3, 2020

util got OOM when i use utp enable

@anacrolix
Copy link
Owner

Do you have cgo enabled, and are using anacrolix/go-libutp? Can you provide any profiles? What kind of run time does it take for you to see the leak?

@ucwong
Copy link
Contributor Author

ucwong commented Apr 5, 2020

cfg.DisableUTP=false
cl, err := torrent.NewClient(cfg)
just set the disable utp as false, the memory used will keep raising, but not if i disable utp

@ucwong
Copy link
Contributor Author

ucwong commented Apr 5, 2020

I think cgo is enable

@anacrolix
Copy link
Owner

Can you provide any profiles? What kind of run time does it take for you to see the leak?

@ucwong
Copy link
Contributor Author

ucwong commented Apr 8, 2020

56161732 56 @ 0xa32e04 0xa32da1 0xf7db26 0x1032e50 0x1028231 0x103b5f2 0x1046ede 0x10471eb 0xa13551
# 0xa32e03 sync.(*Mutex).Unlock+0xa3           /usr/local/go/src/sync/mutex.go:190
# 0xa32da0 sync.(*RWMutex).Unlock+0x40           /usr/local/go/src/sync/rwmutex.go:136
# 0xf7db25 github.com/CortexFoundation/CortexTheseus/vendor/github.com/anacrolix/sync.(*RWMutex).Unlock+0x55  /root/CortexTheseus/build/_workspace/src/github.com/CortexFoundation/CortexTheseus/vendor/github.com/anacrolix/sync/rwmutex.go:26
# 0x1032e4f github.com/CortexFoundation/CortexTheseus/vendor/github.com/anacrolix/torrent.(*lockWithDeferreds).Unlock+0x7f /root/CortexTheseus/build/_workspace/src/github.com/CortexFoundation/CortexTheseus/vendor/github.com/anacrolix/torrent/deferrwl.go:22
# 0x1028230 github.com/CortexFoundation/CortexTheseus/vendor/github.com/anacrolix/torrent.(*Client).unlock+0x30  /root/CortexTheseus/build/_workspace/src/github.com/CortexFoundation/CortexTheseus/vendor/github.com/anacrolix/torrent/client.go:1382
# 0x103b5f1 github.com/CortexFoundation/CortexTheseus/vendor/github.com/anacrolix/torrent.(*Torrent).AddPeers+0xa1  /root/CortexTheseus/build/_workspace/src/github.com/CortexFoundation/CortexTheseus/vendor/github.com/anacrolix/torrent/t.go:221
# 0x1046edd github.com/CortexFoundation/CortexTheseus/vendor/github.com/anacrolix/torrent.(*trackerScraper).announce+0x58d /root/CortexTheseus/build/_workspace/src/github.com/CortexFoundation/CortexTheseus/vendor/github.com/anacrolix/torrent/tracker_scraper.go:126
# 0x10471ea github.com/CortexFoundation/CortexTheseus/vendor/github.com/anacrolix/torrent.(*trackerScraper).Run+0x2aa /root/CortexTheseus/build/_workspace/src/github.com/CortexFoundation/CortexTheseus/vendor/github.com/anacrolix/torrent/tracker_scraper.go:137


cycles/second=2500063193
1305031203356354 1740 @ 0x9f41c2 0x1047162 0xa13501
# 0x9f41c1 runtime.selectgo+0x521            /usr/local/go/src/runtime/select.go:485
# 0x1047161 github.com/CortexFoundation/CortexTheseus/vendor/github.com/anacrolix/torrent.(*trackerScraper).Run+0x271 /root/CortexTheseus/build/_workspace/src/github.com/CortexFoundation/CortexTheseus/vendor/github.com/anacrolix/torrent/tracker_scraper.go:159

489861550598947 5226 @ 0xa2f7dd 0x102c867 0xa13501
# 0xa2f7dc sync.(*Cond).Wait+0x9c            /usr/local/go/src/sync/cond.go:56
# 0x102c866 github.com/CortexFoundation/CortexTheseus/vendor/github.com/anacrolix/torrent.(*connection).writer+0x496 /root/CortexTheseus/build/_workspace/src/github.com/CortexFoundation/CortexTheseus/vendor/github.com/anacrolix/torrent/connection.go:635

380512478750212 5146 @ 0xa2f7dd 0x10167ad 0x1028f89 0x1036897 0xa5e88c 0xa5e88c 0x1033c30 0xb3b36a 0xa5dc97 0xab8809 0xab8814 0xf32ab3 0x104b7fe 0x102f277 0x1024499 0x1023c83 0x1020da8 0xa13501
# 0xa2f7dc sync.(*Cond).Wait+0x9c             /usr/local/go/src/sync/cond.go:56
# 0x10167ac github.com/CortexFoundation/CortexTheseus/vendor/github.com/anacrolix/go-libutp.(*Conn).Read+0x8c   /root/CortexTheseus/build/_workspace/src/github.com/CortexFoundation/CortexTheseus/vendor/github.com/anacrolix/go-libutp/conn.go:159
# 0x1028f88 github.com/CortexFoundation/CortexTheseus/vendor/github.com/anacrolix/torrent.connStatsReadWriter.Read+0x58  /root/CortexTheseus/build/_workspace/src/github.com/CortexFoundation/CortexTheseus/vendor/github.com/anacrolix/torrent/conn_stats.go:119
# 0x1036896 github.com/CortexFoundation/CortexTheseus/vendor/github.com/anacrolix/torrent.(*rateLimitedReader).Read+0xb6  /root/CortexTheseus/build/_workspace/src/github.com/CortexFoundation/CortexTheseus/vendor/github.com/anacrolix/torrent/ratelimitreader.go:43
# 0xa5e88b io.(*multiReader).Read+0xab            /usr/local/go/src/io/multi.go:26
# 0xa5e88b io.(*multiReader).Read+0xab            /usr/local/go/src/io/multi.go:26
# 0x1033c2f github.com/CortexFoundation/CortexTheseus/vendor/github.com/anacrolix/torrent.deadlineReader.Read+0x12f   /root/CortexTheseus/build/_workspace/src/github.com/CortexFoundation/CortexTheseus/vendor/github.com/anacrolix/torrent/handshake.go:27

@ucwong
Copy link
Contributor Author

ucwong commented Apr 8, 2020

Here is some informations I saved before with debug/pprof
I found the number of locks and go routines never when down

@anacrolix
Copy link
Owner

@ucwong Thanks. I'm not sure what's going on there, you have a lot of goroutines blocked on unlocking the Client mutex? What versions of go-libutp and torrent are you on? Could you update to torrent v1.15.0?

@ucwong
Copy link
Contributor Author

ucwong commented Apr 9, 2020

OK, I think i used the latest version, but i will test again
it will be ok when disable utp
ps:i keep seeding some files, the number of mutex and block never go down

@ucwong
Copy link
Contributor Author

ucwong commented Apr 13, 2020

Still OOM at last in utp mode

@anacrolix
Copy link
Owner

Could it be that you're running lots of Torrents, with a lot of connections and trackers? This might be causing a massive amount of contention on the Client lock?

@anacrolix
Copy link
Owner

Do you have a read or write rate limiter set?

@ucwong
Copy link
Contributor Author

ucwong commented Apr 14, 2020

... But it is ok for tcp protocol only, I use default set ,it maybe unlimited

@ucwong
Copy link
Contributor Author

ucwong commented Apr 14, 2020

Any suggestions for utp settings different with tcp

@anacrolix
Copy link
Owner

It's possible there are undocumented, upstream limits to how many connections you can have per utp socket. This information would be helpful:

Could it be that you're running lots of Torrents, with a lot of connections and trackers? This might be causing a massive amount of contention on the Client lock?

@james-lawrence
Copy link
Contributor

james-lawrence commented Apr 16, 2020

@ucwong I have a fork of this library that massively reworks how locking is done. might be worth a look to see it if suffers the same issue. if it doesn't then we can back track possible issues from there potentially.

but i suspect the mutex issue is a red herring.

@ucwong
Copy link
Contributor Author

ucwong commented Apr 17, 2020

@james-lawrence thank you for comment, I have test the new commit , the memory seems to be ok now, but the number of block and mutex is still increasing without OOM. I will keep running it for a bit longer time.
@anacrolix thank you for the latest commits

@ucwong
Copy link
Contributor Author

ucwong commented Apr 17, 2020

The memory is increasing slower, but I think it still will be OOM after long time seeding with UTP

@ucwong
Copy link
Contributor Author

ucwong commented Apr 17, 2020

I found 75 block here, ratelimitreader.go:43

@anacrolix
Copy link
Owner

Are you running with the block and mutex profilers enabled? I'm not sure the results mean what you infer them to mean. I don't have enough information to go on here.

@ucwong
Copy link
Contributor Author

ucwong commented Apr 23, 2020

It shows where is blocked in the code, but I am not sure it is useful. It will oom when I seeding files for long time with UTP on. It is very good in only TCP mod.

@anacrolix
Copy link
Owner

A heap profile after it has run for a long time before it crashes would be very helpful.

@ucwong
Copy link
Contributor Author

ucwong commented Apr 23, 2020

@anacrolix I will make another test
you can get some running infos here http://mainnet.cortexlabs.ai:6060/debug/pprof/
I hope it will be helpful

@anacrolix
Copy link
Owner

@ucwong thanks for sharing that. I would suggest not running with the block or mutex profiling enabled, those won't help with the memory leak as far as I'm aware. How many torrents do you think you have running at a given time? There's a backlog against the dial rate limiter, which I've not seen happen under normal circumstances. The heap profiles also aren't showing anything useful, I'm not sure why. Also what is your CPU usage like? I noticed a lot of CPU devoted to PEX, you might try disabling that.

@anacrolix
Copy link
Owner

@ucwong do you have any more feedback?

@ucwong
Copy link
Contributor Author

ucwong commented Jun 24, 2020

I am using it without UTP, It is ok till now. I am not sure why OOM by with UTP seeding

@ucwong
Copy link
Contributor Author

ucwong commented Aug 4, 2020

@anacrolix
image

It keeps printing this when I use utp

@anacrolix
Copy link
Owner

@ucwong Does the local system support IPv6?

@kslr
Copy link

kslr commented Mar 23, 2021

package main

import (
	"fmt"
	"github.com/PuerkitoBio/goquery"
	"github.com/anacrolix/torrent"
	"log"
	"net/http"
)

func main() {
	config := torrent.NewDefaultClientConfig()
	client, err := torrent.NewClient(config)
	if err != nil {
		log.Panic(client)
	}

	var magnets []string
	for i := 1; i <= 13; i++ {
		url := fmt.Sprintf("https://nyaa.si/?s=seeders&o=desc&p=%d", i)
		response, err := http.Get(url)
		if err != nil {
			log.Fatal(err)
		}
		if response.StatusCode != 200 {
			log.Fatalf("status code error: %d %s", response.StatusCode, response.Status)
		}

		doc, err := goquery.NewDocumentFromReader(response.Body)
		if err != nil {
			log.Fatal(err)
		}
		doc.Find("table > tbody > tr").Each(func(_ int, td *goquery.Selection) {
			td.Find("td").Each(func(i int, a *goquery.Selection) {
				if i == 2 {
					magnet, _ := a.Find("a").Last().Attr("href")
					magnets = append(magnets, magnet)
				}
			})
		})
		_ = response.Body.Close()
	}
	fmt.Printf("all length: %d \n", len(magnets))

	for _, uri := range magnets {
		_, err = client.AddMagnet(uri)
		if err != nil {
			log.Fatal(err)
		}
	}

	select {}
}

If UTP is enabled, memory is quickly depleted, If disabled, it takes about 10 minutes to run out. (~1000 torrent)

ubuntu 20.04 / 32G Ram / go 1.16 / lib 1.15.1 / ipv6 and ipv4

@anacrolix
Copy link
Owner

@ucwong Does the local system support IPv6?

Same question for you @kslr

@kslr
Copy link

kslr commented Mar 24, 2021

@ucwong Does the local system support IPv6?

Same question for you @kslr

Yes, ipv4 and ipv6

@anacrolix
Copy link
Owner

Could subscribers to this issue try again with a recent version of anacrolix/torrent?

@ucwong
Copy link
Contributor Author

ucwong commented Oct 25, 2021

Could subscribers to this issue try again with a recent version of anacrolix/torrent?

Any changes about this ?

@anacrolix
Copy link
Owner

Nothing specific but there has been a lot of churn throughout anacrolix/torrent.

@ucwong
Copy link
Contributor Author

ucwong commented Oct 26, 2021

Nothing specific but there has been a lot of churn throughout anacrolix/torrent.

OK, I am running a long time test and hope it will be fine

@ucwong
Copy link
Contributor Author

ucwong commented Oct 28, 2021

It seems better than before but memory can not be recycled till OOM in utp only mode

@anacrolix
Copy link
Owner

@ucwong do you think this is fixed?

@anacrolix
Copy link
Owner

I think I'm observing this issue when I have seeding enabled. Go reports ~85MB of memory in use, but the process is using ~1.25GB.

@anacrolix
Copy link
Owner

A large memory leak was fixed in anacrolix/go-libutp@0430340. This is included in anacrolix/torrent v1.39.1 and later.

Further fixes may occur from anacrolix/go-libutp#20, but I expect that the above fix handled most issues. It also includes a lot of performance improvements around uTP handling.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants