さて、私はVirtualStringTreeを使用して一種のプロセスマネージャーを作成しています...
1000msに設定されたタイマーでツリーを更新したために問題が発生しました(CPU使用率が高すぎて、アプリケーションが大量のデータ(約20列を埋める)を取得できません。
それで、ある種のキャッシュシステムを構築して、何かが変更されたときにのみツリーを更新できるようにするにはどうすればよいのでしょうか。これが、アプリケーションのCPU使用率を大幅に低下させる鍵であると思われます。
をちょきちょきと切る:
type
TProcessNodeType = (ntParent, ntDummy);
PProcessData = ^TProcessData;
TProcessData = record
pProcessName : String;
pProcessID,
pPrivMemory,
pWorkingSet,
pPeakWorkingSet,
pVirtualSize,
pPeakVirtualSize,
pPageFileUsage,
pPeakPageFileUsage,
pPageFaults : Cardinal;
pCpuUsageStr: string;
pIOTotal: Cardinal;
...
end;
アプリケーションが起動したら、実行中のすべてのプロセスでツリーを埋めます。これは一度だけ呼び出されることを覚えておいてください。後でアプリケーションを実行すると、新しいプロセスまたはwmiを介して終了するプロセスの通知を受け取ったので、後でタイマーで次のプロシージャを呼び出してツリーを更新する必要はありません...
procedure FillTree;
begin
var
NodeData: PProcessData;
Node: PVirtualNode;
ParentNode: PVirtualNode;
ChildNode: PVirtualNode;
Process: TProcessItem;
I : Integer;
begin
ProcessTree.BeginUpdate;
for I := 0 to FRunningProcesses.Count - 1 do
begin
Process := FRunningProcesses[i];
NodeData^.pProcessID := ProcessItem.ProcessID;
NodeData^.pProcessName := ProcessItem.ProcessName;
...
必要なすべてのデータを取得して、次のようにツリーに保存するクラスがあります。
var
FRunningProcesses: TProcessRunningProcesses;
したがって、実行中のすべてのプロセスを列挙したい場合は、次のように呼び出します。
// clears all data inside the class and refills everything with the new data...
FRunningProcesses.UpdateProcesses;
問題は、変更されたデータだけでなく、すべてを列挙しているときにここから始まります。これは、CPUを大量に消費します。
procedure TMainForm.UpdateTimerTimer(Sender: TObject);
var
NodeData: PProcessData;
Node : PVirtualNode;
Process: TProcessItem;
I: Integer;
begin
for I := 0 to FRunningProcesses.Count - 1 do
begin
Application.ProcessMessages;
Process := FRunningProcesses[I];
// returns PVirtualNode if the node is found inside the tree
Node := FindNodeByPID(Process.ProcessID);
if not(assigned(Node)) then
exit;
NodeData := ProcessVst.GetNodeData(Node);
if not(assigned(NodeData)) then
exit;
// now starting updating the tree
// NodeData^.pWorkingsSet := Process.WorkingsSet;
....
基本的に、タイマーはCPU使用率と、次のようなプロセスから取得できるすべてのメモリ情報にのみ必要です。
- Priv.Memory
- ワーキングセット
- ピークワーキングセット
- 仮想サイズ
- PageFileの使用法
- PageFileのピーク使用量
- ページフォールト
- CPU使用率
- スレッド数
- ハンドル数
- GDIハンドル数
- ユーザーハンドル数
- 合計CPU時間
- ユーザーCPU時間
- カーネルCPU時間
したがって、上記のデータをキャッシュして比較する必要があると思います。データが変更された場合、またはどのように、そして何が最も効率的か疑問に思っているだけではないでしょうか。