sys.dm_clr_appdomains (Transact-SQL)

适用于SQL Server

为服务器中的每个应用程序域返回一行。 应用程序域(AppDomain)是Microsoft .NET Framework 公共语言运行时(CLR)中的构造,它是应用程序的隔离单元。 可以使用此视图来了解和排查在 SQL Server Microsoft中执行的 CLR 集成对象的问题。

有多种类型的 CLR 集成托管数据库对象。 有关这些对象的常规信息,请参阅 使用公共语言运行时 (CLR) 集成生成数据库对象。 每当执行这些对象时,SQL Server 将创建一个 AppDomain,在该 AppDomain 下可以加载和执行所需的代码。 AppDomain隔离级别是每个所有者每个数据库的一个 AppDomain。 也就是说,用户拥有的所有 CLR 对象始终在同一 个 AppDomain 每个数据库中执行(如果用户在不同数据库中注册 CLR 数据库对象,则 CLR 数据库对象将在不同的应用程序域中运行)。 代码完成执行后,AppDomain 不会销毁。 而是将其缓存在内存中以供将来执行。 从而可以提高性能。

有关详细信息,请参阅 应用程序域

列名称 数据类型 描述
appdomain_address varbinary(8) AppDomain地址。 用户拥有的所有托管数据库对象始终在同一 AppDomain 中加载。 可以使用此列在 sys.dm_clr_loaded_assemblies 中查找当前在此 AppDomain 中加载的所有程序集。
appdomain_id int AppDomainID。 每个 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。 执行此视图将创建强 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 生命周期中发生的时间。 可以使用此信息跟踪 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)