Warum haben dm_os_memory_clerks MEMORYCLERK_SQLCLR-Werte auf einem NUMA-Knoten?

7

Wir verwenden eine gespeicherte SQLCLR-Prozedur für die Aktivierung des Service Brokers, und ich möchte den vom CLR-Code verwendeten Speicher überwachen. Beim Betrachten sys.dm_os_memory_clerkssehe ich, dass nur der NUMA-Knoten 1 Seiten hat, die dem MEMORYCLERK_SQLCLRTyp zugeordnet sind. Der Server verfügt über zwei 8-Core-CPUs und führt SQL 2014 CU6 aus.

Wird das erwartet? Oder sollte ich sehen, dass auf beiden Knoten Speicher verwendet wird, wie ich es tue MEMORYCLERK_SQLBUFFERPOOL?

Abfrage:

SELECT DOMC.memory_node_id
    , DOMC.pages_kb
    , DOMC.virtual_memory_reserved_kb
    , DOMC.virtual_memory_committed_kb 
FROM sys.dm_os_memory_clerks DOMC where type = 'MEMORYCLERK_SQLCLR'

Ergebnisse:

memory_node_id pages_kb             virtual_memory_reserved_kb virtual_memory_committed_kb
-------------- -------------------- -------------------------- ---------------------------
0              88232                12607744                   1408652
1              0                    0                          0
64             0                    0                          0
msgisme
quelle

Antworten:

3

Leider gibt es nicht viele Informationen zu den Besonderheiten der SQLCLR-Speichernutzung. Ich fand jedoch die folgenden zwei Ressourcen als Ausgangspunkt hilfreich:

Aus diesen und den verschiedenen DMVs und den MSDN-Seiten, die erklären (nun, es erklärt nicht viel, aber technisch ist es mehr als nichts), wie diese DMVs irgendwie funktionieren, habe ich die unten gezeigten Abfragen zusammengestellt. Wenn man diese auf einigen verschiedenen Systemen ausführt, scheint sich die SQLCLR-Speicherzuweisung auf einen bestimmten zu konzentrieren memory_node_id, aber es gibt immer noch eine gewisse Zuweisung auf anderen Knoten, zumindest im Hinblick auf den Proc-Cache. Sofern jemand keine gegenteiligen Beweise oder Informationen hat, wird das, was Sie erleben, "erwartet".


Diese Abfrage meldet die Basisinformationen:

SELECT domc.*
FROM   sys.dm_os_memory_clerks domc
WHERE  domc.[type] LIKE '%CLR%'
AND    domc.[memory_node_id] <> 64;

Sie werden feststellen, dass [type]einige weitere Speicherplatz beanspruchen können, wenn Sie keinen bestimmten angeben . Insgesamt 4 Arten, die ich gesehen habe, sind:

  • MEMORYCLERK_SQLCLR,
  • MEMORYCLERK_SQLCLRASSEMBLY
  • CACHESTORE_CLRPROC
  • CACHESTORE_CLRUDTINFO

Wenn Sie sich fragen, warum ich aus [memory_node_id]64 herausfiltere , führen Sie Folgendes aus :

SELECT * FROM sys.dm_os_nodes;

und Sie werden sehen, dass node_id von 64 DAC (Dedicated Administrator Connection) ist.

Im Folgenden erhalten Sie die Gesamtsummen für die beiden wichtigen Felder. Beachten Sie, dass sich die Felder in SQL Server 2012 geändert haben, sodass Sie das Feld auswählen müssen, das für die Version von SQL Server geeignet ist, auf der es verwendet wird:

-- SQL Server 2012, 2014, and 2016:
SELECT SUM(domc.pages_kb) AS [TotalPagesKb],
       SUM(domc.virtual_memory_committed_kb) AS [TotalVirtualMemoryKb]
FROM   sys.dm_os_memory_clerks domc
WHERE  domc.[type] LIKE '%CLR%'
AND    domc.[memory_node_id] <> 64;

-- SQL Server 2005, 2008, and 2008 R2:
SELECT SUM(domc.single_pages_kb + domc.multi_pages_kb) AS [TotalPagesKb],
       SUM(domc.virtual_memory_committed_kb) AS [TotalVirtualMemoryKb]
FROM   sys.dm_os_memory_clerks domc
WHERE  domc.[type] LIKE '%CLR%'
AND    domc.[memory_node_id] <> 64;

Die nächste Abfrage zeigt die Beziehung zwischen "memory_clerks" und "memory_objects":

SELECT domc.*, N' █ ' AS [  ], domo.*
FROM   sys.dm_os_memory_clerks domc
LEFT JOIN sys.dm_os_memory_objects domo
        ON domo.page_allocator_address = domc.page_allocator_address
WHERE  domc.[type] LIKE N'%CLR%'
AND    domc.[memory_node_id] <> 64;

Die folgenden Abfragen sind eine fokussiertere Version der ersten Abfrage (und ähneln eher der Abfrage in der Frage), aber die Felder wurden in SQL Server 2012 geändert, sodass Sie diejenige auswählen müssen, die für die Version von SQL Server geeignet ist benutzt auf:

-- SQL Server 2012, 2014, and 2016:
SELECT domc.memory_node_id,
       domc.[type],
       domc.pages_kb,
       domc.virtual_memory_committed_kb
FROM   sys.dm_os_memory_clerks domc
WHERE  domc.[type] LIKE '%CLR%'
AND    domc.[memory_node_id] <> 64;

-- SQL Server 2005, 2008, and 2008 R2:
SELECT domc.memory_node_id,
       domc.[type],
       (domc.single_pages_kb + domc.multi_pages_kb) AS [pages_kb],
       domc.virtual_memory_committed_kb
FROM   sys.dm_os_memory_clerks domc
WHERE  domc.[type] LIKE '%CLR%'
AND    domc.[memory_node_id] <> 64;

AKTUALISIEREN:

Ich habe einige zusätzliche Tests auf einem System mit zwei Prozessoren durchgeführt, indem ich zwei Datenbanken erstellt und mithilfe einer statischen Variablen 80 MB in jede der Datenbanken geladen habe. Ich habe zwei Datenbanken anstelle einer erstellt, um zu sehen, ob eine AppDomain auf einem Speicherknoten verbleiben muss, ob sie zumindest eine andere AppDomain auf einem anderen Speicherknoten platzieren kann, um die Dinge zu verteilen. Die Ergebnisse:

  • Alle 160 MB über beide DBs (und damit über beide AppDomains) gingen auf den Speicherknoten 0
  • Alle 160 MB gingen in den virtuellen Speicher, nicht in den physischen Speicher. Es war nur das [virtual_memory_committed_kb]Feld sys.dm_os_memory_clerks, das zunahm. Auch die Spalte "Commit Size" im "Task Manager" spiegelte diesen Anstieg wider.
Solomon Rutzky
quelle