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

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

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

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Linux

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

Q&A

解決済

3回答

2731閲覧

psコマンドのRESの合計とfreeコマンドのusedの結果が大きく異なる

mosa

総合スコア218

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Linux

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

1グッド

0クリップ

投稿2018/05/16 01:35

編集2018/05/24 04:07

いつもありがとうございます。

初歩的な質問です。
Xmx1g のJavaプロセスを2つ実行している状態で、topコマンドを実行し、メモリでソートした結果が以下のようになります。

top - 09:36:43 up 2 days, 30 min, 4 users, load average: 1.74, 2.67, 3.20 Tasks: 123 total, 1 running, 122 sleeping, 0 stopped, 0 zombie %Cpu(s): 6.4 us, 7.8 sy, 0.0 ni, 84.5 id, 0.0 wa, 0.0 hi, 0.2 si, 1.1 st KiB Mem : 6110664 total, 906804 free, 4953016 used, 250844 buff/cache KiB Swap: 1679356 total, 1640796 free, 38560 used. 840744 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 5562 **** 20 0 8433012 812704 13448 S 41.4 13.3 411:42.10 java 9198 **** 20 0 10.301g 181752 13016 S 33.8 3.0 325:39.89 java 5333 **** 20 0 150352 5844 4512 S 0.0 0.1 0:00.11 sshd 17195 **** 20 0 150352 5844 4512 S 0.0 0.1 0:00.11 sshd 18777 **** 20 0 150352 5844 4512 S 0.0 0.1 0:00.12 sshd 5351 **** 20 0 150352 5840 4512 S 0.0 0.1 0:00.10 sshd

JavaプロセスのRESがそれぞれ 812704(793MB), 181752(177MB) であるにもかかわらず、全体の使用量が 4953016(4.7GB) used となっています。
Javaプロセスを終了させると全体の使用量は100MB程度に落ちます。
JavaプロセスのXmxを2GB程度にすると OOM Killer が走ってしまうことがあります。 (→訂正。Xmx1gでも OOM Killer 走りました)
ヒープサイズ1GBのJavaを2つ実行しただけで4.6GBも使用してしまうのはなぜでしょうか。


CentOS7.3
qemu-kvm
Java8
ほかに必要な情報などありましたらご指摘ください。


■追記1

全く同じ状態の再現に時間がかかったのでやや違いますが別日に計測したものです。
※ここではXmx1g の Javaプロセスを1つ実行。
※Javaアプリはソケットを大量のオープンする。

Xmx1gのJavaプロセス1つ実行しただけでメモリを3.0GB使用しています。
いずれ上記と同じようにOOMKillerが走るのだと思います。

●実行前のfreeコマンド

$ free -h total used free shared buff/cache available Mem: 5.8G 78M 5.6G 1.8M 129M 5.6G Swap: 1.6G 45M 1.6G

●実行中のfreeコマンド

$ free -h total used free shared buff/cache available Mem: 5.8G 3.0G 2.7G 1.5M 137M 2.6G Swap: 1.6G 78M 1.5G

●実行中のpsコマンド

USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND **** 25720 29.8 2.7 5012132 169256 ? Sl 5月20 576:01 /usr/bin/java -Xmx1g -cp ****.jar 【クラス名】

●実行中のtopコマンド

top - 09:00:04 up 6 days, 23:53, 3 users, load average: 0.03, 0.06, 0.05 Tasks: 120 total, 2 running, 117 sleeping, 0 stopped, 1 zombie %Cpu(s): 0.4 us, 0.4 sy, 0.0 ni, 99.1 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem : 6110664 total, 2819844 free, 3149420 used, 141400 buff/cache KiB Swap: 1679356 total, 1598804 free, 80552 used. 2728760 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 25720 **** 20 0 5012132 169256 5644 S 0.0 2.8 576:06.73 java 21260 postfix 20 0 89648 4008 3004 S 0.0 0.1 0:00.03 pickup 865 root 20 0 223672 2340 1252 S 0.0 0.0 12:02.66 snmpd

■追記2

●実行前の/proc/meminfo

$ cat /proc/meminfo MemTotal: 6110664 kB MemFree: 4422364 kB MemAvailable: 4365788 kB Buffers: 2108 kB Cached: 132708 kB SwapCached: 0 kB Active: 1224816 kB Inactive: 95480 kB Active(anon): 1185740 kB Inactive(anon): 8380 kB Active(file): 39076 kB Inactive(file): 87100 kB Unevictable: 0 kB Mlocked: 0 kB SwapTotal: 1679356 kB SwapFree: 1679356 kB Dirty: 28 kB Writeback: 0 kB AnonPages: 1185480 kB Mapped: 37008 kB Shmem: 8640 kB Slab: 109856 kB SReclaimable: 18484 kB SUnreclaim: 91372 kB KernelStack: 150720 kB PageTables: 26208 kB NFS_Unstable: 0 kB Bounce: 0 kB WritebackTmp: 0 kB CommitLimit: 4734688 kB Committed_AS: 10572224 kB VmallocTotal: 34359738367 kB VmallocUsed: 157676 kB VmallocChunk: 34359406588 kB HardwareCorrupted: 0 kB AnonHugePages: 743424 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB DirectMap4k: 61404 kB DirectMap2M: 6230016 kB

●実行後の/proc/meminfo

$ cat /proc/meminfo MemTotal: 6110664 kB MemFree: 127508 kB MemAvailable: 19592 kB Buffers: 0 kB Cached: 21648 kB SwapCached: 1944 kB Active: 484260 kB Inactive: 531108 kB Active(anon): 473628 kB Inactive(anon): 520768 kB Active(file): 10632 kB Inactive(file): 10340 kB Unevictable: 0 kB Mlocked: 0 kB SwapTotal: 1679356 kB SwapFree: 1322472 kB Dirty: 20 kB Writeback: 0 kB AnonPages: 991884 kB Mapped: 10892 kB Shmem: 808 kB Slab: 152988 kB SReclaimable: 21008 kB SUnreclaim: 131980 kB KernelStack: 159664 kB PageTables: 27516 kB NFS_Unstable: 0 kB Bounce: 0 kB WritebackTmp: 0 kB CommitLimit: 4734688 kB Committed_AS: 11211048 kB VmallocTotal: 34359738367 kB VmallocUsed: 157676 kB VmallocChunk: 34359406588 kB HardwareCorrupted: 0 kB AnonHugePages: 792576 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB DirectMap4k: 61404 kB DirectMap2M: 6230016 kB

■追記3

shared や buff/cache の利用が少ない中において、

(ps auxコマンド6列目RESの合計) $ sudo ps aux | sed '1d' | sed 's/\s\s*/ /g' | awk '{m+=$6} END{print m/1024 "MB.";}' 626.613MB.

の結果と

$ free -h total used free shared buff/cache available Mem: 5.8G 5.5G 119M 780K 172M 13M Swap: 1.6G 435M 1.2G

のusedの結果がだいぶ近くなると思っていたのですが、600MBと5.5GBでかなりかけ離れてしまっています。
おそらく私に何か知識が足りないためだとは思うのですが。。。

■追記4

slabtopの結果でも特に100MBを超えているものはありませんでした。

manzyun👍を押しています

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

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

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

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

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

TaichiYanagiya

2018/05/16 12:42

free コマンドではどうなっていますでしょうか?
mosa

2018/05/17 00:46

OOM Killerが走ってしまったのでやりなおしています。約1日くらいで同様の状態が再現できますので、すみませんがもうしばらくお待ちください。
mosa

2018/05/21 00:13

遅くなってすみません。やや異なる感じになってしまいましたが、再度実行し、freeコマンドの結果をつけました。
退会済みユーザー

退会済みユーザー

2018/05/24 03:19

psコマンド の略はクラス名及びクラスパスだけにしてください。
mosa

2018/05/24 04:08

ご指摘ありがとうございます。修正しました。省略した部分はjarへのクラスパスとクラス名のみでした。
guest

回答3

0

自己解決

原因がわかりました。
Javaアプリはソケットを大量にオープンするものでしたが、一方的に送信のみを行い、受信(InputStream)を完全に無視していたため、受信バッファがメモリを消費していたことが原因でした。
受信バッファがいっぱいになるとACKを返さずそれぞれのソケット通信が停止するはずですが、接続数が多すぎてその前にメモリが足りなくなりOOMKillerが発生していました。
ソケットバッファはヒープとは別に、システムの物理メモリが消費されるためと思われます。プロセスの消費メモリとしても計上されないようです。
InputStreamをskipするコードを入れたところ同事象は発生しなくなりました。
ご回答いただいた皆様ありがとうございました。

クライアント側プログラム

Java

1public class MySocket{ 2 public static void main(String[] args) throws IOException{ 3 for(int i = 0; i < 1000; i++){ 4 new Thread(() -> { 5 try(Socket socket = new Socket("localhost", 9999); OutputStream out = socket.getOutputStream()){ 6 7 // ここのコメントを外すとメモリオーバーはなくなる 8 // InputStream in = socket.getInputStream(); 9 // new Thread(() -> { 10 // try{ 11 // while(true) in.skip(Long.MAX_VALUE); 12 // }catch(IOException ignore){ 13 // } 14 // }).start(); 15 16 byte b = Byte.MIN_VALUE; 17 while(true){ 18 out.write(b++); 19 Thread.sleep(2); 20 } 21 }catch(Exception ignore){ 22 } 23 }).start(); 24 } 25 } 26}

サーバ側プログラム

Java

1public class MyServerSocket{ 2 public static void main(String[] args) throws IOException{ 3 ServerSocket serverSocket = new ServerSocket(9999); 4 while(true){ 5 Socket socket = serverSocket.accept(); 6 new Thread(() -> { 7 try(InputStream in = socket.getInputStream(); OutputStream out = socket.getOutputStream()){ 8 while(true) out.write(in.read()); 9 }catch(IOException ignore){ 10 } 11 }).start(); 12 } 13 } 14}

投稿2018/06/17 04:47

mosa

総合スコア218

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

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

0

プロセス自体のメモリ使用量と buff/cache を合わせても、used には程遠いですね。
メモリファイルシステム(tmpfs)を利用していませんでしょうか?
OS によりますが、/dev/shm/, /run/, /tmp/ などが tmpfs になっていて、その下に GB 単位でファイルを作成しているなど。

投稿2018/05/21 11:44

TaichiYanagiya

総合スコア12146

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

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

mosa

2018/05/22 03:55

ありがとうございます。ご指摘の点、確認してみます。CentOS7なので、デフォルト?でtmpfsを使用しています。再度実行して状態を確認してみます。 # df -h ファイルシス サイズ 使用 残り 使用% マウント位置 /dev/mapper/centos-root 14G 1.4G 13G 11% / devtmpfs 3.0G 0 3.0G 0% /dev tmpfs 3.0G 0 3.0G 0% /dev/shm tmpfs 3.0G 8.5M 3.0G 1% /run tmpfs 3.0G 0 3.0G 0% /sys/fs/cgroup /dev/vda1 1014M 153M 862M 16% /boot tmpfs 597M 0 597M 0% /run/user/1000
TaichiYanagiya

2018/05/22 04:58

tmpfs はほとんど使用していないですね。 あとは kernel 側で使っているものでしょうか。 Slab キャッシュとか。 起動前、起動後、時間経過後の /proc/meminfo を比較して、増えている項目を調べると何かわかるかもしれません。
mosa

2018/05/22 05:16

すみません。上記のdf -h の結果は実行前です。紛らわしいことしてすみません。メモリの増加は1日くらいかかります。/proc/meminfo とってみます。ありがとうございます。
mosa

2018/05/23 03:10

追記2を追加しました。meminfoについては特に私が気になったものはなかったのですが。。。追記3についてもお時間があればご指摘いただければ幸いです。
mosa

2018/05/23 03:10

あ、ちなみに実行中もtmpfsの使用はほとんどありませんでした。
TaichiYanagiya

2018/05/23 07:08

tmpfs でも Slab キャッシュでもないとすると、ちょっとわかりません。 不可解なのは、available が free より少なくなっていること(実行前も)。 仮想環境ではないですよね? CentOS 7 標準ではない、別の kernel を使っているとか?
mosa

2018/05/24 02:07

すみません。情報書いていませんでしたが、qemu-kvm仮想環境です。
guest

0

それは、file cacheで使われているためです。

fileをdiskから読む時に一度メモリにコピーしてから読みます。
プログラムがfileを読み込んで処理している途中にも、OSがその先を読む という並列分業が行われています。

メモリが余分にあれば、その先読みした部分を捨てる必要性はないので、読んだままになります。メモリを他の用途に使うときには、先読み情報はどんどん捨てられていきます。またfileを沢山読めば、その時にも不要そうな部分は捨てられます。不要・必要はOSが推定します。一般的には古いものから捨てていきます。推定には、いつ最後に使ったか・繰り返し使ったか・いつ読んだか の大体3点を基準にいくつかの方法があります。

topはいろいろアレなので、メモリ使用量をチェックするなら free の方がいいです。
いまさら聞けないLinuxとメモリの基礎&vmstatの詳しい使い方

投稿2018/05/19 23:15

gm300

総合スコア580

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

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

mosa

2018/05/21 00:17

ありがとうございます。 別日の実行でfreeコマンドの結果を付けました。 buff/cache は実行前後であまり変わっていないようです。 また、file cache でのメモリ使用の場合もOOMKillerが 走ってしまうものなのでしょうか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問