私は、メモリと計算負荷の両方が高いプロジェクトに取り組んでいます。実行の大部分は、FixedThreadPool
. 要するに; 複数のリモート ロケーションから (URL 接続を使用して) データをフェッチし、分析対象のオブジェクトをデータに取り込むための 1 つのスレッドと、これらのオブジェクトを選択して分析を実行するn 個のスレッドがあります。編集:以下のコードを参照してくださいBlockingQueue
現在、このセットアップは、OpenSUSE 11.3 を実行している私の Linux マシンで魅力的に機能しますが、同僚が Win7 を実行している非常によく似たマシンでそれをテストしており、キューのポーリングでタイムアウトのカスタム通知を取得しています (以下のコードを参照)。私は彼女のマシンでプロセッサの使用状況を監視しようとしてきましたが、私のマシンでは意図したとおりにプロセッサの使用率が上限に達している間、ソフトウェアは CPU の 15% を超えないようです。
私の質問は、これはキューの「飢餓」の兆候でしょうか? プロデューサースレッドが十分なCPU時間を取得していない可能性がありますか? もしそうなら、プール内の特定のスレッドに高い優先度を与えるにはどうすればよいですか?
更新: 私は問題を特定しようとしてきましたが、喜びはありませんでした...しかし、いくつかの新しい洞察を得ました。
JVisualVM を使用してコードの実行をプロファイリングすると、非常に特異な動作が示されます。メソッドは、CPU 時間の短いバーストで呼び出され、その間に数秒間進行がありません。これは、何らかの形で OS がプロセスにブレーキをかけていることを意味します。
ウイルス対策およびバックアップ デーモンを無効にしても、問題に大きな影響はありません。
タスク マネージャー (ここで推奨) を使用して java.exe (唯一のインスタンス) の優先度を変更しても、何も変更されません。(そうは言っても、Javaに「リアルタイム」の優先順位を与えることはできず、「高い」プライオリティに満足する必要がありました)
ネットワークの使用状況をプロファイリングすると、データの出入りの良好な流れが示されるので、それがボトルネックではないと推測しています (プロセスの実行時間のかなりの部分を占めていますが、私はすでに知っており、 Linux マシンで得られるもの)。
Win7 OS がプロジェクトの CPU 時間をどのように制限しているかについてのアイデアはありますか? それがOSでない場合、何が制限要因になる可能性がありますか? もう一度強調したいのですが、マシンは同時に他の計算集約的な処理を実行しておらず、私のソフトウェア以外の CPU にはほとんど負荷がかかっていません。これは私を夢中にさせています...
編集: 関連するコード
public ConcurrencyService(Dataset d, QueryService qserv, Set<MyObject> s){
timeout = 3;
this.qs = qserv;
this.bq = qs.getQueue();
this.ds = d;
this.analyzedObjects = s;
this.drc = DebugRoutineContainer.getInstance();
this.started = false;
int nbrOfProcs = Runtime.getRuntime().availableProcessors();
poolSize = nbrOfProcs;
pool = (ThreadPoolExecutor) Executors.newFixedThreadPool(poolSize);
drc.setScoreLogStream(new PrintStream(qs.getScoreLogFile()));
}
public void serve() throws InterruptedException {
try {
this.ds.initDataset();
this.started = true;
pool.execute(new QueryingAction(qs));
for(;;){
MyObject p = bq.poll(timeout, TimeUnit.MINUTES);
if(p != null){
if (p.getId().equals("0"))
break;
pool.submit(new AnalysisAction(ds, p, analyzedObjects, qs.getKnownAssocs()));
}else
drc.log("Timed out while waiting for an object...");
}
} catch (Exception ex) {
ex.printStackTrace();
String exit_msg = "Unexpected error in core analysis, terminating execution!";
}finally{
drc.log("--DEBUG: Termination criteria found, shutdown initiated..");
drc.getMemoryInfo(true); // dump meminfo to log
pool.shutdown();
int mins = 2;
int nCores = poolSize;
long totalTasks = pool.getTaskCount(),
compTasks = pool.getCompletedTaskCount(),
tasksRemaining = totalTasks - compTasks,
timeout = mins * tasksRemaining / nCores;
drc.log("--DEBUG: Shutdown commenced, thread pool will terminate once all objects are processed, " +
"or will timeout in : " + timeout + " minutes... \n" + compTasks + " of " + (totalTasks -1) +
" objects have been analyzed so far, " + "mean process time is: " +
drc.getMeanProcTimeAsString() + " milliseconds.");
pool.awaitTermination(timeout, TimeUnit.MINUTES);
}
}
このクラスQueryingAction
は、指定されたオブジェクトでRunnable
データ取得メソッドを呼び出してから. このクラスは、 の 1 つのインスタンスに対してすべての数値処理を行います。QueryService
BlockingQueue
AnalysisAction
MyObject