sys.dm_clr_appdomains (Transact-SQL)
为服务器中的每个应用程序域返回一行。 应用程序域 (AppDomain) 是 Microsoft .NET Framework 公共语言运行时 (CLR) 中的构造,它是应用程序的隔离单元。 您可以使用该视图来了解并排除 Microsoft SQL Server 中执行的 CLR 集成对象遇到的问题。
有多种类型的 CLR 集成托管数据库对象。 有关这些对象的常规信息,请参阅使用公共语言运行时 (CLR) 集成生成数据库对象。 只要执行这些对象,SQL Server 便会创建一个 AppDomain,可以在其下加载和执行必需的代码。 AppDomain 的隔离级别为每个所有者每个数据库一个 AppDomain。 也就是说,某用户拥有的所有 CLR 对象始终在每个数据库的同一 AppDomain 中执行(如果用户在不同数据库中注册了 CLR 数据库对象,则 CLR 数据库对象将在不同的应用程序域中运行)。 代码执行完成后,并不会销毁 AppDomain, 而是缓存在内存中以备将来执行, 从而可以提高性能。
有关详细信息,请参阅应用程序域。
列名 |
数据类型 |
说明 |
---|---|---|
appdomain_address |
varbinary(8) |
AppDomain 的地址。 用户拥有的所有托管数据库对象始终都在同一 AppDomain 中加载。 您可以使用该列查找当前在 sys.dm_clr_loaded_assemblies 中的这个 AppDomain 中加载的所有程序集。 |
appdomain_id |
int |
AppDomain 的 ID。 每个 AppDomain 都有一个唯一的 ID。 |
appdomain_name |
varchar(386) |
AppDomain 的名称,由 SQL Server 分配。 |
creation_time |
datetime |
创建 AppDomain 的时间。 因为 AppDomains 进行了缓存并可重复使用以提高性能,所以 creation_time 不一定是执行代码的时间。 |
db_id |
int |
在其中创建了此 AppDomain 的数据库的 ID。 存储在两个不同数据库中的代码无法共享同一个 AppDomain。 |
user_id |
int |
能够在此 AppDomain 中执行其对象的用户的 ID。 |
state |
nvarchar(128) |
AppDomain 的当前状态的描述符。 AppDomain 可以处于从创建到删除的不同状态中。 有关详细信息,请参阅本主题的“备注”部分。 |
strong_refcount |
int |
对 AppDomain 进行强引用的数目。 这反映了当前正在执行并且使用此 AppDomain 的批的数目。 请注意,执行此视图将创建一个 strong refcount;即使当前没有代码正在执行,strong_refcount 的值也将等于 1。 |
weak_refcount |
int |
对 AppDomain 进行弱引用的数目。 这表示在 AppDomain 中缓存的对象数目。 执行托管数据库对象时,SQL Server 将其缓存在 AppDomain 中以供将来重新使用, 从而可以提高性能。 |
cost |
int |
AppDomain 的开销。 开销越大,在面临内存不足压力时卸载该 AppDomain 的可能性也越大。 开销通常取决于重新创建该 AppDomain 所需的内存量。 |
value |
int |
AppDomain 的值。 值越低,在面临内存不足压力时卸载该 AppDomain 的可能性也越大。 值通常取决于使用该 AppDomain 的连接或批的数目。 |
total_processor_time_ms |
bigint |
自进程启动后在当前应用程序域中执行的过程中所有线程所用的处理器总时间(毫秒)。 这等效于 System.AppDomain.MonitoringTotalProcessorTime。 |
total_allocated_memory_kb |
bigint |
应用程序域自创建以来进行的所有内存分配的总大小 (KB)(不减去已收集的内存大小)。 这等效于 System.AppDomain.MonitoringTotalAllocatedMemorySize。 |
survived_memory_kb |
bigint |
在已知当前应用程序域所引用的最近一次全面的阻塞收集之后仍剩余的字节数 (KB)。 这等效于 System.AppDomain.MonitoringSurvivedMemorySize。 |
注释
在 dm_clr_appdomains.appdomain_address 和 dm_clr_loaded_assemblies.appdomain_address 之间存在一对多关系。
下表列出了可能的状态值,它们的说明以及它们在 AppDomain 生命周期中出现的时间。 您可以在不必分析 Windows 事件日志的情况下使用该信息跟踪 AppDomain 的生命周期及监视可疑或重复性的 AppDomain 实例卸载。
AppDomain 初始化
状态 |
说明 |
---|---|
E_APPDOMAIN_CREATING |
正在创建 AppDomain。 |
AppDomain 使用情况
状态 |
说明 |
---|---|
E_APPDOMAIN_SHARED |
运行时 AppDomain 已准备就绪可供多个用户使用。 |
E_APPDOMAIN_SINGLEUSER |
AppDomain 可用于 DDL 操作中。 此行为不同于 E_APPDOMAIN_SHARED,在后者中,共享的 AppDomain 用于 CLR 集成执行,而非 DDL 操作。 此类 AppDomain 独立于其他并发操作。 |
E_APPDOMAIN_DOOMED |
按计划应该卸载 AppDomain,但当前多个线程正在其中执行。 |
AppDomain 的清除
状态 |
说明 |
---|---|
E_APPDOMAIN_UNLOADING |
SQL Server 已请求 CLR 卸载 AppDomain,这通常是因为包含托管数据库对象的程序集已更改或已删除。 |
E_APPDOMAIN_UNLOADED |
CLR 已卸载 AppDomain。 这通常是由于 ThreadAbort、OutOfMemory 或用户代码中未处理的异常导致的升级过程的结果。 |
E_APPDOMAIN_ENQUEUE_DESTROY |
AppDomain 已在 CLR 中卸载并设置为由 SQL Server 销毁。 |
E_APPDOMAIN_DESTROY |
AppDomain 正处在由 SQL Server 销毁的过程。 |
E_APPDOMAIN_ZOMBIE |
AppDomain 已由 SQL Server 销毁;但是,并未清除所有对 AppDomain 的引用。 |
权限
需要对数据库具有 VIEW SERVER STATE 权限。
示例
以下示例显示如何查看给定程序集的 AppDomain 的详细信息:
select appdomain_id, creation_time, db_id, user_id, state
from sys.dm_clr_appdomains a
where appdomain_address =
(select appdomain_address
from sys.dm_clr_loaded_assemblies
where assembly_id = 500)
以下示例显示如何查看给定 AppDomain 中的所有程序集:
select a.name, a.assembly_id, a.permission_set_desc, a.is_visible, a.create_date, l.load_time
from sys.dm_clr_loaded_assemblies as l
inner join sys.assemblies as a
on l.assembly_id = a.assembly_id
where l.appdomain_address =
(select appdomain_address
from sys.dm_clr_appdomains
where appdomain_id = 15)