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

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

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

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

メモリリーク

メモリリークは、プログラムファイルがメモリの解放に失敗した時に起こります。

Q&A

解決済

5回答

11498閲覧

psコマンドでメモリ使用量が増えている場合はメモリリークしているのか

Ykkykk

総合スコア140

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

メモリリーク

メモリリークは、プログラムファイルがメモリの解放に失敗した時に起こります。

2グッド

2クリップ

投稿2021/05/10 02:51

C言語で作成したループで同じ処理を行い続けるプログラムを長時間動かしていると、psコマンドのVSZとRSSが漸増していくのですが、この場合メモリリークしていると考えるのが妥当でしょうか。

Valgrindで処理を動かしてもメモリリークは見つからないのですが、psコマンドで見るとメモリ使用量が増えています。数分おきに一定程度ずつ増えるわけでもなく、何らかのタイミングで増えているようです。

こういった場合、Valgrindを使用する以外にメモリリークを調査する方法はあるのでしょうか。目視で確認していく形でしょうか。

漠然とした質問で申し訳ありませんが、ご教示いただけますと幸いです。よろしくお願いいたします。

Waki285👍を押しています

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

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

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

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

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

AbeTakashi

2021/05/10 03:36

まずは可能な範囲でソースコードを提示した方が良いと思います。psコマンドのVSZとRSSが増えていくのはメモリリークでも良くありますが、違う原因でそれが起きている可能性もありますし。ご本人も自覚されていると思いますが現状ですと質問が漠然すぎるので、求めている回答が出てくるのは厳しいと思います。
Ykkykk

2021/05/10 04:37

コメントいただきありがとうございます。私もそうしたいのですが、ソースコード全体が数千行以上ある複数のモジュールから作成されているため、すべてを掲載できず、また再現性のある小さなソースコードにもできない状態です。。。やはり難しいですね。ありがとうございます。
AbeTakashi

2021/05/10 05:30

例え数千行でもご自分で書かれたコードであればなんとなくこの辺かな?みたいな勘所はあるんじゃないかと思いますが、その辺に絞ってGDBとか使いながら地道に探していくしかなさそうですね。そうじゃないのであればかなりの難作業になりそうです。いっそのことC++とかpythonとかで書き直した方が結果早いかもしれません。あとはメモリリーク起きててもそれ以外に問題起きてないのであれば、適当なタイミングでプロセス再起動するような処理を入れるとか?
guest

回答5

0

ベストアンサー

多くのOSでmallocした領域をfreeした場合、freeされたメモリは、つなぎ合わせることなくその大きさのブロックとして管理されているようです。
そのため、例えば16キロバイトの領域を16個とってfreeした後に128キロバイトの領域をとると、freeした領域は再利用されません。16キロバイト以下のメモリ要求があったときには再利用されるかもしれません。
したがって、psコマンドのVSZとRSSが漸増していてもメモリリークかどうかはプログラムによるとしかいえません。

投稿2021/05/10 06:54

ppaul

総合スコア24668

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

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

Ykkykk

2021/05/10 07:40

ご回答いただきありがとうございます。OS側ではそのようにメモリの再利用がなされているのですね。勉強になりました。psコマンドだけでではメモリリークしているかどうか判別できないということですね。ありがとうございました。
Ykkykk

2021/05/13 02:19

今更ながら申し訳ないのですが、こちらのご回答のような知識はどのようにして学習できるのでしょうか。。。参考となる書籍やウェブサイトなどがありましたらご教示いただけますと幸いです。もしコメント見ていらっしゃいましたらよろしくお願いいたします。
ppaul

2021/05/17 22:49

こういう話は、あまり資料が出回らないのです。 この手の情報を必要とする人はOSとかシステムをやる人ですので、ソースを読むのになれているのです。 興味があれば以下をどうぞ。 https://code.woboq.org/userspace/glibc/malloc/malloc.c.html
Ykkykk

2021/05/18 07:00

ご返信いただきありがとうございます。ライブラリのソースコードを読むしかないのですね。。。勉強いたします。ありがとうございました!
guest

0

メモリが増え続けることをメモリリークと言うのならメモリリークですが
あなたの書いたプログラムの問題かまでは特定できないと思います。

私も自分のプログラムを長時間(数日~数週間)動かし続けると rss,vsz が
少しずつ増える件を調べたことがあります。結局原因不明でしたが、このとき
ありうることとして

(1) OSのどれかの関数が少量のメモリを確保し、そのまま返さない

(2) Linuxのmallocはbrkを使う場合とmmapを使う場合があり、mmapの場合は
freeでOSに返りますが、brk はOSに返しません。brk を使うmalloc/freeが
順不動で繰り返されると領域が断片化して、vszが増えていく可能性がある

という推測をしました。多分(1)が大きいと思うのですが、どうしようもないので
実質的に問題とならない(他のプロセスを邪魔しない)なら仕方ないかなと思ってます。

投稿2021/05/10 05:46

sigsegv

総合スコア895

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

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

Ykkykk

2021/05/10 07:40

ご回答いただきありがとうございます。psコマンドだけではコード自体にメモリリークが含まれているか、やはり確認することは難しいのですね。ありがとうございました。
guest

0

詳細はソースコードを見ないとなんとも言えないのですが、一般論としては VSZ や RSS が増加し続けているからといってメモリリークとは限りません。

プロセスが OS に対してメモリを要求することでプロセスが使えるメモリが増えるわけですが、 OS が管理するメモリはある程度に大きい単位であり、それを malloc が小分けするという形をとります。 そして free をしてもそれがすぐさま OS の管理下に返却されるというわけではなく未割り当てのままプロセスが所持し続けて次の malloc のときに再利用されます。

ps コマンドで見えるのは OS がプロセスに対してどれだけメモリを渡しているかであって、プロセス内部で割り当て済みなのか未割り当てなのかは見えないのです。

OS からメモリを割り当ててもらう処理、あるいはメモリを返却する処理というのは重いらしく、それほど頻繁に発生しないように malloc を実装するのが一般的なようです。 OS にメモリを要求することなくプロセス内部で mallocfree を繰り返し、それでも足りなくなったときに OS に要求するので ps コマンドで監視しているとたまにポンとメモリ使用量が増える、というような挙動になるのだと思います。

メモリ使用量の実体を監視したいのであればプロファイラ機能付きの malloc の実装 (jemalloc など) がありますので、そういうのを活用してもよいかもしれないですね。

投稿2021/05/10 05:19

SaitoAtsushi

総合スコア5675

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

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

Ykkykk

2021/05/10 07:38

ご回答いただきありがとうございます。freeしてもただちにメモリが解放されることはないということは知っていたのですが、大変勉強になりました。また、jemallocのご紹介いただきありがとうございます。こちらも参考にしたいと思います。
guest

0

https://www.hboehm.info/gc/leak.html こういうのもあるようです。

投稿2021/05/10 13:35

fu7mu4

総合スコア1088

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

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

Ykkykk

2021/05/10 23:56

このようなツールもあるのですね。お教えいただきありがとうございます。こちらの使用方法なども確認したいと思います!
guest

0

他の方が書いているように、プログラムバグでメモリーリークしていなくても、mallocfreeを繰り返すと、メモリーのフラグメンテーションにより、使用メモリーが増えていく可能性があります。

フラグメンテーションを減らす方法としては、
・必要最小限のサイズでmallocするのでなく、サイズを切り上げて決まったサイズ、例えば100、1000のどちらかでしかmallocしない等
・大きなサイズでmallocして(あるいはmallocでなくsbrkで)、その中の小分けの割り当てを自分で管理する。freeはしない
などが考えられるかと思います。

投稿2021/05/10 13:34

otn

総合スコア85768

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

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

Ykkykk

2021/05/10 23:55

ご回答いただきありがとうございます。処理の中で結構頻繁にmallocとfreeを行っているのが原因のような気もしてきました。。。sbrkという関数もあるのですね。ご教示いただきありがとうございます。また一般的な質問になってしまうのですが、あまりmallocとfreeは行わない方がよいということでしょうか?素人考えだと常に動的に文字列分のメモリを確保できた方が良いのかと思っていたのですが、配列として決められた大きさで指定してしまった方が良いのでしょうか。もっともケースバイケースかと思いますが。。。
otn

2021/05/11 01:56

> あまりmallocとfreeは行わない方がよいということでしょうか? いいえ。 メモリーのフラグメンテーションが発生する可能性のことを考慮して使えば良いかと。
Ykkykk

2021/05/11 02:41

再度ご回答いただきありがとうございます。フラグメンテーションについて考慮して使うということですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問