Memahami apa yang terjadi di Linux dengan ps, top, dan gratis

0

Saya menjalankan program java saya pada mesin 12 core 24 thread. Mereka memiliki beberapa proses yang berjalan secara bersamaan. Tampaknya saya melakukan terlalu banyak proses sehingga seluruh tugas membuat mesin sangat lambat.

Inilah informasi teratas

Tasks: 556 total,   2 running, 554 sleeping,   0 stopped,   0 zombie
Cpu(s):  0.1%us,  0.4%sy,  0.0%ni, 63.2%id, 36.3%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:  16295248k total, 16169560k used,   125688k free,     3300k buffers
Swap: 18530296k total, 10867972k used,  7662324k free,    46188k cached

Tampaknya proses saya berorientasi pada konsumsi memori sehingga hampir semua memori digunakan oleh mereka. Dalam informasi teratas, apa yang saya tidak mengerti adalah mengapa hanya 2 tugas yang berjalan alih-alih 23 (saya telah mengirim 23 proses).

free -g
             total       used       free     shared    buffers     cached
Mem:            15         15          0          0          0          0
-/+ buffers/cache:         15          0
Swap:           17         10          7

Tampaknya semua memori digunakan dan ditukar membuat mesin melambat.

ps -e -o pid,%cpu,%mem,vsz,rss,comm= --sort=vsz
29707  5.6  4.2 6268732 685660 java
29712  5.2  3.9 6268732 647352 java
...
30269  3.2  4.3 6268732 704676 java
30334  4.8  4.2 6268732 689544 java

Ada 23 proses java tersebut. Menjumlahkan semua% cpu, sangat mendekati 100%. Tetapi informasi teratas menunjukkan bahwa CPU tidak sibuk.

Cpu(s):  0.1%us,  0.4%sy,  0.0%ni, 63.2%id, 36.3%wa,  0.0%hi,  0.0%si,  0.0%st

Saya googled berapa ukuran vsz dan rss tetapi tidak mengetahuinya. Saya berasumsi bahwa unit ini dalam kilo byte. Menonton vsz maka proses java menggunakan 6268732kb * 23 = 144.180.836 = ~ 144gb, yang tampaknya tidak mungkin untuk dimasukkan ke dalam RAM karena itu jauh melebihi RAM saya (16gb), jadi hanya 700000kb * 23 = ~ 16gb yang dimasukkan ke dalam memori (dengan info rss, yang merupakan bagian dari penyimpanan data dalam RAM). Karena seringnya pertukaran dan pengalihan konteks membuat sistem melambat.

Saya tidak tahu kesimpulan saya benar atau tidak. Tolong beri saya saran dan bagaimana saya bisa memperbaiki masalah.

Tambahkan detail lebih lanjut:

vmstat -a -S M
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 r  b   swpd   free  inact active   si   so    bi    bo   in   cs us sy id wa st
 2 29  16792    124   2105  13152    0    0    29    23    2    0  1  0 95  4  0

Saya tidak tahu bagaimana cara menafsirkan data vmstat. Agak aneh karena swpd: jumlah memori virtual yang digunakan terlihat tinggi sementara si dan 0.

Marcus Thornton
sumber
Sepertinya swap benar-benar banyak digunakan. Perhatikan bahwa hanya sekitar 150 MB RAM yang tidak digunakan untuk proses! Sementara memiliki 10 GB pada swap -> Anda kekurangan RAM. --- Gunakan vmstatuntuk melihat kesalahan halaman memori virtual aktual ( sidan so). Gunakan vmstat 1untuk menunjukkannya secara terus menerus dalam interval kedua. vmstatjuga menunjukkan aktivitas IO. Gunakan iotopuntuk pemantauan aktivitas IO per proses yang lebih rinci.
pabouk

Jawaban:

0

Sistem Anda jelas hilang RAM.

  • tambahkan lebih banyak RAM (berharap Anda tidak perlu menambahkan hingga 128 GB)
  • batasi jumlah instance JVM karena masing-masing menggunakan memori virtual 6 GB.
  • tune mereka untuk menggunakan lebih sedikit memori, ini adalah 64 bit JVM, lihat bendera -Xmx.

Tidak ada masalah CPU.

Jlliagre
sumber
Lalu mengapa menjumlahkan semua% cpu sangat dekat dengan 100%?
Marcus Thornton
1
Yah, saya perkirakan jumlahnya antara 1200% hingga 2400% pada sistem yang terikat CPU.
jlliagre
Maksud Anda% dalam hal satu inti, bukan cpu seluruh sistem?
Marcus Thornton
Dalam termal (perangkat keras) benang bahkan.
jlliagre
Jadi untuk mesin 24 thread, kapasitas% cpu maksimum adalah 2400 adalah informasi ps?
Marcus Thornton
0

Kesimpulan Anda memang benar. Ukuran memori dalam KB, baik vsz dan rss, karena Anda dapat memeriksa diri Anda dengan melihat halaman manual untuk ps, di bagian STANDAR FORMAT SPECIFIER .

Ada juga pemeriksaan lain yang dapat Anda lakukan: rss (resident set size, yaitu memori non-swap yang digunakan oleh setiap proses) adalah sekitar 700MB per proses. Jika Anda memiliki 23 proses seperti itu, itu menyumbang 15GB memori yang digunakan (bukan swap).

Juga, ukuran total memori fisik Anda + swap jauh lebih kecil dari yang dibutuhkan oleh eksekusi simultan dari 23 tugas ini, 16GB vs 144GB. Jadi tampaknya tidak ada satu proses pun yang mengalokasikan jumlah memori yang diperlukan saat ini.

Jadi, apa pilihan Anda? Cukup jalankan dua proses sekaligus, karena ukurannya sedemikian rupa sehingga Anda dapat menyimpannya sepenuhnya dalam memori Anda, tanpa menukar. Setelah selesai, muat dua lagi. Ini dapat dengan mudah dilakukan dengan skrip bash, dengan perintah tunggu :

   my_job < file1.txt &
   my_job < file2.txt &
   wait 1 2
   my_job < file3.txt
   my_job < file4.txt
   wait 3 4....

Ini juga akan meninggalkan Anda beberapa ruang dalam memori untuk tetap di sana / tmp, / run, dan sebagainya, yang berarti kemampuan sistem Anda untuk melakukan secara interaktif akan sedikit terpengaruh.

Opsi kedua (mungkin yang pertama), adalah bertanya pada diri sendiri bagaimana Anda bisa mendapatkan kode java 7GB ... tapi itu pertanyaan untuk StackOverflow

Sunting:

Saya membalas komentar Marcus Thornton di sini:

Jika saya dapat memperbaiki masalah memori, ..., apakah baik untuk mengirim semua tugas sekaligus?

Iya dan tidak. Jika Anda memperbaiki masalah memori, maka Anda tentu dapat melakukan lebih dari 2 pekerjaan secara bersamaan. Tetapi bisakah Anda menjalankan 23? Saya pikir Anda melebih-lebihkan kegunaan Multi-threading . Multi-threading adalah prosesor tunggal, dengan dua konteks eksekusi, yang memungkinkan penggunaan paralel unit fungsional yang berbeda pada prosesor yang sama. Tetapi jika tugasnya sama , karena terikat dalam kasus Anda, kemungkinan besar mereka akan menggunakan unit fungsional yang sama, sehingga mereka akan antri seperti halnya jika tidak ada multi-threading. Multi-threading bukan hal yang sama seperti harus prosesor independen, dan itu memungkinkan kenaikan kecepatan marjinal, paling banter.

BTW, bagaimana CPU yang Anda miliki? Anda mengatakan prosesor, bukan cpu. Perintah berikut

  /bin/cat /proc/cpuinfo | /bin/egrep 'processor|model name|cache size|core|sibling|physical'

akan membantumu.

MariusMatutiae
sumber
VSZ (dijumlahkan sebagai 144 GB) tentu saja bukan memori yang dibutuhkan oleh suatu proses! Ini adalah ruang memori virtual yang dialokasikan dari suatu proses yang tidak perlu sesuai dengan memori fisik yang dialokasikan sama sekali (RAM, swap, file yang dipetakan memori). Jumlah ini dalam banyak kasus tidak berguna.
pabouk
Dengan solusi Anda, saya harus mencari tahu pid dari setiap pekerjaan sehingga saya bisa membiarkan tugas menunggu mereka, kan?
Marcus Thornton
@MarcusThornton: waitadalah built-in shell. Anda dapat menggunakan salah satu wait %job_natau wait pid. Cara termudah adalah hanya waitmenunggu semua pekerjaan latar belakang shell. Anda tidak akan dapat menggunakan solusi sederhana ini jika Anda menjalankan beberapa pekerjaan latar belakang tambahan.
pabouk
1
@Pabouk, Java tidak mengalokasikan memori fisik (RAM), itu allocs (cadangan, mungkin dengan overcommitment) memori virtual seperti proses userland biasa lainnya. Statistik vsz jelas berguna, terutama dengan JVM yang cenderung tidak menggunakan zona alokasi yang sama untuk objek baru.
jlliagre
@MarcusTonton Ya, tetapi sangat mudah: setelah kerja &, variabel shell $! memiliki PID pekerjaan. Jadi: job1 &; PID1 = $!; job2 &; PID2 = $!; tunggu $ PID1 $ PID2. itu dia.
MariusMatutiae