オブジェクト プーリング
COM+ のオブジェクト プーリング サービスを使用すると、各オブジェクトを最初から作成するオーバーヘッドを軽減できます。オブジェクトがアクティブになると、そのオブジェクトがプールから取り出されます。オブジェクトが非アクティブになると、オブジェクトはプールに返却され、次の要求を待ちます。
オブジェクト プーリングを設定するには、System.EnterpriseServices.ServicedComponent クラスから派生させたクラスに ObjectPoolingAttribute 属性を適用します。
最大接続数を制御する接続プーリングに対して、オブジェクト プーリングでは、使用する接続の数を制御します。オブジェクト プーリングと接続プーリングの重要な相違点を次に示します。
- **作成。**接続プーリングを使用しているときは、作成は同じスレッドで行われます。そのため、プールに何もない場合は、接続が作成されます。オブジェクト プーリングでは、新しいオブジェクトを作成するかどうかをプールが判断します。オブジェクト プーリングが既に最大値に達している場合は、次に利用できるオブジェクトが供給されます。オブジェクトの作成に時間がかかり、そのオブジェクトを長時間使用しない場合、これは必要な動作となります。
- **最小値および最大値の適用。**接続プーリングでは、最小値および最大値は適用されません。オブジェクト プーリングの最大値は、アプリケーションをスケーリングするときに必要です。何千という要求をわずかな数のオブジェクトに多重送信することが必要な場合もあります。TPC/C ベンチマークは、このような多重送信を前提にしています。
COM+ のオブジェクト プーリングは、.NET Framework マネージ SQL クライアントの接続プーリングと実質的には同じです。たとえば、作成は別のスレッドで行われ、最小値と最大値が適用されます。
**メモ **アプリケーション ドメインは、オブジェクト プーリングの動作に影響します。Microsoft Windows 2000 では、アプリケーション アクティベーションが Library に設定されていて、複数のアプリケーション ドメインが存在する場合、プーリングされるオブジェクトはすべて、既定のアプリケーション ドメインに作成され、複数のクライアント間で共有されます。同じ条件で Microsoft Windows XP および Windows Server 2003 を使用した場合は、アプリケーション ドメインごとにオブジェクト プールが 1 つ用意されます。複数のアプリケーション ドメインが存在し、アプリケーション アクティベーションをサーバーに設定して、いずれかのオペレーティング システムを使用すると、プロセス外部のクライアントは、既定のアプリケーション ドメインのオブジェクト プールを使用します。
TestObjectPooling
クラスに対してサイズ制限とタイムアウト制限を設定する例を次に示します。
<ObjectPooling(MinPoolSize := 2, MaxPoolSize := 5, _
CreationTimeout := 20000)> _
Public Class TestObjectPooling
Inherits ServicedComponent
Public Sub Perform ()
' Method contents go here.
End Sub
Public Overrides Sub Activate()
' Called when removed from the pool.
End Sub
Public Overrides Sub Deactivate()
' Called before deactivating or placing back in pool.
End Sub
Public Overrides Function CanBePooled() As Boolean
' Called after Deactivate. Indicate your vote here.
Return True
End Function
End Class
[C#]
[ObjectPooling(Enabled=true, MinPoolSize=2, MaxPoolSize=5, CreationTimeOut=20000)]
public class TestObjectPooling : ServicedComponent
{
public void Perform ()
{
// Method contents go here.
}
public override void Activate()
{
// Called when removed from the pool.
}
public override void Deactivate()
{
// Called before deactivating or placing back in pool.
}
public override bool CanBePooled()
{
// Called after Deactivate. Indicate your vote here.
return true;
}
}
クライアント
Public Class App
Overloads Public Shared Sub Main(args() As String)
Dim order As New TestObjectPooling()
order.Perform()
' To return the object to the object pool, use DisposeObject.
' This returns the object to the pool and allows it to be reused.
' If this call is not made, the garbage collector returns it to the pool
' in a non-deterministic fashion, which hinders performance
' of an application that depends on object pooling to conserve
' expensive resources.
ServicedComponent.DisposeObject (order)
End Sub
End Class
[C#]
public class App
{
public static int Main(string[] args)
{
TestObjectPooling order = new TestObjectPooling();
order.Perform();
/* To return the object to the object pool, use DisposeObject.
This returns the object to the pool and allows it to be reused.
If this call is not made, the garbage collector returns it to the pool
in a non-deterministic fashion, which hinders performance
of an application that depends on object pooling to conserve
expensive resources. */
ServicedComponent.DisposeObject (order);
}
}
**メモ **一般的に、サービス コンポーネントを使用する場合は、クライアントから DisposeObject を呼び出す必要はありません。ただし、ジャスト イン タイム (JIT: Just-in-Time) アクティベーション サービスが有効ではないときに、COM+ オブジェクト プーリング サービスを使用している場合は呼び出す必要があります。この場合、オブジェクトをプールに返しても安全であるかどうかを確認するために、オブジェクトの処理が終わったら COM+ に通知する必要があります。一般的に、プーリングされたオブジェクトについて一度に 1 つだけ呼び出しを行う場合は、オブジェクト プーリングと共に JIT アクティベーションを有効にすることをお勧めします。参照を取得し、それに対して複数の呼び出しを行う場合は、JIT アクティベーションを使用せずにオブジェクト プーリングを使用するとパフォーマンスが向上する場合があります。
参照
利用可能な COM+ サービスの概要 | ObjectPoolingAttribute クラス | System.EnterpriseServices