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

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

ただいまの
回答率

90.87%

  • Java

    12802questions

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

  • Linux

    3364questions

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

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

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 217

mosa

score 199

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

初歩的な質問です。
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   520 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を超えているものはありませんでした。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • mosa

    2018/05/21 09:13

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

    キャンセル

  • asahina1979

    2018/05/24 12:19

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

    キャンセル

  • mosa

    2018/05/24 13:08

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

    キャンセル

回答 3

check解決した方法

0

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

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

public class MySocket{
  public static void main(String[] args) throws IOException{
    for(int i = 0; i < 1000; i++){
      new Thread(() -> {
        try(Socket socket = new Socket("localhost", 9999); OutputStream out = socket.getOutputStream()){

          // ここのコメントを外すとメモリオーバーはなくなる
          // InputStream in = socket.getInputStream();
          // new Thread(() -> {
          //   try{
          //     while(true) in.skip(Long.MAX_VALUE);
          //   }catch(IOException ignore){
          //   }
          // }).start();

          byte b = Byte.MIN_VALUE;
          while(true){
            out.write(b++);
            Thread.sleep(2);
          }
        }catch(Exception ignore){
        }
      }).start();
    }
  }
}

 サーバ側プログラム

public class MyServerSocket{
    public static void main(String[] args) throws IOException{
        ServerSocket serverSocket = new ServerSocket(9999);
        while(true){
            Socket socket = serverSocket.accept();
            new Thread(() -> {
                try(InputStream in = socket.getInputStream(); OutputStream out = socket.getOutputStream()){
                    while(true) out.write(in.read());
                }catch(IOException ignore){
                }
            }).start();
        }
    }
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

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

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

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/21 09:17

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

    キャンセル

0

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/22 12: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

    キャンセル

  • 2018/05/22 13:58

    tmpfs はほとんど使用していないですね。

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

    キャンセル

  • 2018/05/22 14:16

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

    キャンセル

  • 2018/05/23 12:10

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

    キャンセル

  • 2018/05/23 12:10

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

    キャンセル

  • 2018/05/23 16:08

    tmpfs でも Slab キャッシュでもないとすると、ちょっとわかりません。

    不可解なのは、available が free より少なくなっていること(実行前も)。
    仮想環境ではないですよね?
    CentOS 7 標準ではない、別の kernel を使っているとか?

    キャンセル

  • 2018/05/24 11:07

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

    キャンセル

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

  • ただいまの回答率 90.87%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Java

    12802questions

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

  • Linux

    3364questions

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