質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

Q&A

1回答

5453閲覧

goroutineで無限ループをメモリリークさせずに実行する方法を教えて頂けないでしょうか?

Palo_Punte

総合スコア21

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

0グッド

1クリップ

投稿2020/05/20 16:17

編集2020/05/20 16:22

初心者です。for文を試しに書いていた時に気になった事を質問をさせて頂きたいと思いました。
簡略化しているのでおかしい所はあるかもしれないのですが、上のコードはhoge関数をループさせ、下のコードはgoroutineで実行している関数の処理をループさせています。
下の処理の方だけおそらくメモリリークかな?と思うのですがエラーで処理が止まってしまいました。
fatal error: runtime: out of memory
goroutine 79 [running]:
(略)
goroutine 12 [sleep]:
(略)
とかなり長いエラーの文が表示されました。
下のコードではメモリリークが起き上のコードでは起きないのはどうしてなのでしょうか?
下のコードでメモリリークがおきずgoroutineで処理をし続けるループを書くにはどのようにすれば良いのでしょうか?
実用性はないかもしれないのですが勉強として気になりました。
メモリーの開放処理を書けばいのであればどのように書けば良いのか教えて頂きたいです。
よろしくお願いいたします。

func main(){ var aiueo = []{"あ","い","う",(略),"ん"}//あ〜んまでのスライス for { hoge(aiueo) } } func hoge(aiueo []string){ var wg sync.WaitGroup for _, v := range aiueo { wg.Add(1) go hoge2(v,&wg) } wg.Wait() } func hoge2(v string, wg *sync.WaitGroup){ defer wg.Done() fmt.Println(v) }
func main(){ var aiueo = []{"あ","い","う",(略),"ん"}//あ〜んまでのスライス hoge(aiueo) } func hoge(aiueo []string){ var wg sync.WaitGroup for _, v := range aiueo { wg.Add(1) go hoge2(v) } wg.Wait()//DoneがないのでWaitが発動しない } func hoge2(v string){ for{ fmt.Println(v) } }

go言語1.13

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

みたところ、どちらもメモリーリークらしいコードは見当たりません。
上の例は「50音分のgoroutine」を起動と終了を繰り返していて、
下の例は「終わらないgoroutineを50音分」起動して待ち続ける。

ただ下の例はビジーループといって、PCのCPUリソースを使い切る使い方になってしまいますので、
PCの動作そのものが重くなるでしょう。この時何らかの不都合が発生することはありえます。
(Goのプロセスだけでなく他のアプリのOSへのメモリ返却の機会が得られにくいなど)

追記

詳しくruntime: out of memoryの原因を探りたい場合は以下の方法が便利です。

importとinit関数を追加しておきます。

go

1import( 2 "net/http" 3 _ "net/http/pprof" 4) 5 6func init() { 7 go http.ListenAndServe(":8080", nil) 8}

http://localhost:8080/debug/pprofを開きます。

そのブラウザ画面のなかで、goroutineの数やメモリ割り当ての合計サイズなどが確認できます。

投稿2020/05/21 00:56

編集2020/05/21 02:46
nobonobo

総合スコア3367

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Palo_Punte

2020/05/21 01:50

ご回答ありがとうございます リソースを使いきらず、waitで待たず複数の処理をゴルーチンで非同期で繰り返し動かし続けるには下のコードはどのように書けば良いのでしょうか?
nobonobo

2020/05/21 02:10

バッファ付きの出力をつかったり、ファイルに書き出す、通信で送信など、 実際に効率的な入出力(IO)を行うのであれば入出力(IO)待ちが入るので上記のコードのまま問題はなくなると思います。
Palo_Punte

2020/05/21 15:57

ありがとうございます まだ試した事がないため、すぐにできるかはわからないのですがやってみようと思います pprofも教えて頂きありがとうございました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問