sys.dm_clr_appdomains (Transact-SQL)

适用于:SQL Server

为服务器中的每个应用程序域返回一行。 应用程序域 (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) 由 SQL Server 分配的 AppDomain 的名称。
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 的值为 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_addressdm_clr_loaded_assemblies.appdomain_address 之间存在一对多关系。

下表列出了可能 的状态 值、其说明以及它们在 AppDomain 生命周期中发生的时间。 可以使用此信息来跟踪 AppDomain 的生命周期,并监视可疑或重复 的 AppDomain 实例卸载,而无需分析 Windows 事件日志。

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。 这通常是由于 ThreadAbortOutOfMemory 或用户代码中未经处理的异常而导致的升级过程的结果。
E_APPDOMAIN_ENQUEUE_DESTROY AppDomain 已在 CLR 中卸载,并设置为由SQL Server销毁。
E_APPDOMAIN_DESTROY AppDomain 正在被SQL Server销毁。
E_APPDOMAIN_ZOMBIE AppDomain 已被SQL Server销毁;但是,并非所有对 AppDomain 的引用都已被清除。

权限

需要对数据库具有 VIEW SERVER STATE 权限。

SQL Server 2022 及更高版本的权限

需要对服务器具有 VIEW SERVER PERFORMANCE 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);  

另请参阅

sys.dm_clr_loaded_assemblies (Transact-SQL)
与公共语言运行时有关的动态管理视图 (Transact-SQL)