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

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

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

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

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

Q&A

解決済

2回答

12209閲覧

Eclipseでシングルスレッドで実行しても、CPU(4コア8スレッド)がほぼ100%になる

ratetail

総合スコア32

Java

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

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

Eclipse

Eclipseは、IBM社で開発された統合開発環境のひとつです。2001年11月にオープンソース化されました。 たくさんのプラグインがあり自由に機能を追加をすることができるため、開発ツールにおける共通プラットフォームとして位置づけられています。 Eclipse自体は、Javaで実装されています。

1グッド

1クリップ

投稿2017/05/10 03:20

編集2017/05/10 16:09

###前提・実現したいこと
Windows7Pro、Eclipse4.6.3 neonで、Javaプログラムを単純なシングルスレッドで実行すれば
Windows側のCPUも1スレッド分だけが最大になると思っていたが
なぜそうならないのかの理由及び、そのような設定があるのかを知りたい。

###発生している問題・エラーメッセージ
Eclipse上でdebug実行する、及びWindowsコマンドプロンプト上で「java classXX」で実行すると、現状Windows側のCPUをほぼ使い切る。

###該当のソースコード

java

1List<String> listStr = new ArrayList<String>(); 2Thread th1 = new Thread(new Runnable(){ 3 @Override 4 public void run(){ 5 for(int m = 0; m < 10; ++m){//10回分 6 listStr.clear(); 7 long st = System.currentTimeMillis(); 8 for(int i = 0; i < 10000000; ++i){ 9 listStr.add(String.valueOf(i)); 10 } 11 long ed = System.currentTimeMillis(); 12 System.out.println(listStr.size() + " " + (ed-st)); 13 } 14 } 15}); 16th1.start();

###補足情報(言語/FW/ツール等のバージョンなど)

Eclipse上及び、Windowsコマンドプロンプトで、Javaをマルチスレッドで実行しても、シングルスレッドで実行しても
作業効率上げるために最適化を図ってシングルスレッドで動作しているように実行しながら
マルチスレッドで扱っているということでしょうか?

umyu👍を押しています

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

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

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

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

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

guest

回答2

0

Java の処理系の実際の動作は詳しく知りませんが、何やら根本的なところでの誤認があるように見えます。

私の知る限り、Java のプログラムは、JavaVM という仮想環境の中で動作するはずです。仮想環境の中でシングルスレッド動作するよう設定したからと言って、仮想環境自体がシングルスレッド動作する必要はどこにもありません。仮想環境内でシングルスレッド処理では起こりえない問題が発生しない限り、仮想環境自体はいくらでもマルチスレッド処理される可能性があるはずです。

また、Java で言うシングルスレッド/マルチスレッド処理の意味するところと、Windows で言うシングルスレッド/マルチスレッド処理の意味するところがそもそも違う可能性がある点にも注意が必要です。

実際のところ、論理 8core ある環境で、Windows で言う「マルチスレッドに対応したアプリ」でも、「マルチプロセスに対応していないアプリ」は CPU リソースを12.5% までしか使うことができません。

それ以上使えるのは、Windows 的にはマルチプロセス処理と呼ばれる処理を行っている場合だけです。他回答へのコメントを見る限り、JavaVMは、これを行っているようです。

大事なことは、Javaプログラムの実行負荷を考える場合に、実環境のCPU利用率と安易に直結させようとするのは無理があるということですので、Windowsにおけるマルチプロセスとマルチスレッドの具体的な違いについてはとりあえず置いておきます。

投稿2017/05/12 06:41

himazin.blm

総合スコア581

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

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

0

ベストアンサー

そもそも、「シングルスレッドのプロセスだから CPU を一つしか使わない」というわけではありません。同時に使わないだけで、実行するコアが違うことはありえます。(まあプロセススケジューラでその辺は回避するようになってはいますが)

また、java をプロンプトから起動したときとは異なり、Eclipse のデバッガから動かしているのであれば、実際の java プログラムの に、デバッガそのものも動いていますから、当然こちらが CPU を食っていても全然おかしくありません。
100% になっているというのはデバッガがアイドルタイムもすべて奪っているだけで、別に処理が重いことを意味しているわけではないからです。
※デバッガは入出力から何からキャッチしようとしているでしょうから、理解できる動きです

投稿2017/05/10 09:51

tacsheaven

総合スコア13703

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

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

ratetail

2017/05/10 15:44

ご回答ありがとうございます。 すみません、質問後に、いろいろテストしていたのですが Windowsコマンドプロンプトで”「java」実行でCPUが12~13%使われる”と書いていましたが その際の「java実行」では、正確にはオプションを付加しヒープダンプなどを取り、同時に実行中のjavaプロセスをjstatにも監視させていた為、使用率が12~13%になっていました。 そこで違いが出ていると認識しておりませんでした、申し訳ありません。 オプションなしで「java classX」で実行したところ、Eclipseで実行されるのと同じようにCPUがほぼ100%となり、計測時間も、Eclipseで計測したものと同じようになりました。 現状のテスト結果では「シングルスレッドでも、全CPUリソースを使う」という結果になってしまったのですが、こちらなぜだか分かりますでしょうか?
tacsheaven

2017/05/11 01:23

Javaでいう「スレッド」と、CPU や OS のいう「スレッド」は異なります。 ですから、Java のコードがマルチスレッドになっていなかったとしても、Java VM 自体がマルチスレッドで全コアのアイドルタイムを奪うことは、おかしなことではないのです。
ratetail

2017/05/12 02:54

ご回答いただいてから、その後、いろいろ調べたり、実験して、以下の結論に至りました。 説明の便宜上 CPU4コア8スレッドうちの1スレッドを、1CPUスレッドとする。 Javaのmainスレッドや、Threadなどで1つ作成したスレッドを、1Javaスレッドとする。 1Javaスレッドで、最大使用できるCPUリソースは、1CPUスレッド分(CPU全体の12~13%)が上限となる。 1CPUスレッドで、複数のJavaスレッドを実行する事が出来る。 1プロセスで、CPU4コア8スレッドを使い切る事が出来る。 今回のケースで、Javaコード側ではシングルスレッドで作成していたのにCPU4コア8スレッドを 全て使い切っていた理由は、おっしゃる通りJavaVM部分が、残りのCPUリソースを消費していました。 作成したJavaコードを、Windowsコマンドプロンプトから「java classXX」と実行すると Javaコードのスレッド(main)以外に、以下のものが実行されていました。 Service Thread C1 CompilerThread3 C2 CompilerThread2 C2 CompilerThread1 C2 CompilerThread0 Attach Listener Signal Dispatcher Finalizer Reference Handler main VM Thread GC task thread#0 (ParallelGC) GC task thread#1 (ParallelGC) GC task thread#2 (ParallelGC) GC task thread#3 (ParallelGC) GC task thread#4 (ParallelGC) GC task thread#5 (ParallelGC) GC task thread#6 (ParallelGC) GC task thread#7 (ParallelGC) VM Periodic Task Thread Java実行後、スレッドダンプを取り、Windowsのパフォーマンスモニタで確認したところ Javaコード側でシングルスレッドで作成し、実行すると、使用するリソース自体は、1CPUスレッド分を 使いきるだけですが、そのとき他のCPUリソースを使用していたのは「GC task thread#XX (ParallelGC)」 の部分でした。このParallelGCの8個全てが、それぞれ1CPUスレッド分(計:全CPUリソースの12~13%×8) を使い切っていました。 なので、Javaコードのシングルスレッドで実際に使用していたのは1CPUスレッド分のみでも その他のCPUリソースはJavaVM側で実行されているプログラムが使用しているため 「Javaコードでシングルスレッドで作成して実行しても、CPU4コア8スレッドを使い切る状態が発生する」 ということになると。 Javaコード側の1Javaスレッドが使用するCPUリソースが、1CPUスレッド分かどうかを確認するため 以下のコードを実行。 Thread th1 = new Thread(new Runnable(){ @Override public void run(){ while(true){ } } }); Thread th2 = new Thread(new Runnable(){ @Override public void run(){ while(true){ } } }); th1.start(); th2.start(); 同様に確認したところ、今回のコードでは、ParallelGCはCPUをまったく消費せず Javaコード側の2Javaスレッドのみが、それぞれ1CPUスレッド分を使い切っていました。 またそのとき、Windowsタスクマネージャのjava.exeプロセスは24~25%(2CPUスレッド分) で張り付いていることも確認できました。 なので、CPUリソースがあまっていても「1Javaスレッドは、全CPUリソースの12~13%(1CPUスレッド分) 以上使用できない」という理解になりました。 以上ですが、勘違いしているところ、間違っているところなど、何かありましたら ご指摘いただければと思います。
yohhoy

2017/05/12 03:48

> このParallelGCの8個全てが、それぞれ1CPUスレッド分(計:全CPUリソースの12~13%×8)を使い切っていました。 名前どおりJVM内部のGCスレッドですから、それらがCPUを使い切ってしまうというのは何かがおかしくなっていると推測されます。(EclipseやJVM不具合の可能性も含めて) > CPUリソースがあまっていても「1Javaスレッドは、全CPUリソースの12~13%(1CPUスレッド分)以上使用できない」という理解になりました。 これは正しいと思いますよ。Javaの1スレッドは1つのCPUスレッド分以上のリソースを使うことはできません。ちなみに"CPUスレッド"は"論理コア(logical core)"と呼ばれることもあります。
tacsheaven

2017/05/12 04:13

テストソースは大量の String の生成と List への登録、そしてそれを使うことなく破棄しているので、GC が大量に発生するのは確かです。あとは実行時のメモリ量指定で、GC の頻度が増えたか。 ※GC中は実行が止まるからとにかく急いで GC を完了させようとするはずなので、CPUパワー全部持ってってる可能性が
ratetail

2017/05/14 04:15

皆様、ご回答ありがとうございます。 今回の主質問についての問題は、解決する事が出来ました。 また、実験結果について補足しますと 今回のコード直前でclearしている場合は各GCが使う論理コアは それぞれ10~40%程度をジグザグしますが clearをしない場合は、GCのそれぞれの論理コアはほぼ100%に張り付いていました。 あまりに多すぎるからなのか、そのあたりまでは、今回知りたい情報の範囲を超えていると判断したため、不要と考えて調査はしていませんでした。 論理コアと言うんですね。情報ありがとうございます。 また、それぞれのジャンルにおいて、マルチコア、マルチプロセス、マルチタスク、マルチスレッドなど、色々あるようですが、問題になった際に、また新しく質問として作成しようと思います。 どうもありがとうございます。
tacsheaven

2017/05/15 00:34

ちなみに1スレッドかどうか確認するためのコードでパラレルGCが動かないのは当然で、GCしなければならないようなメモリの確保と開放が発生していないからです。(変数を宣言してないでしょ?) ガベージコレクションとはどういうもので、特に Java の場合はどのようなタイミングでどのゴミを消して再利用できるようにするか、理解しておくと大規模なシステムを作るときに多少は役に立ちます。GC をいかに抑えるか、というのは性能に影響するので(Full GC になるとプログラムが止まってしまうので、いらぬ面倒を引き起こす)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問