Сборка мусора с COM-объектами в powershell - PullRequest
1 голос
/ 03 марта 2020

Я создал следующую функцию для очистки всех ссылок на com-объекты в конце скрипта:

function TrashCompactor ($reflist) {

foreach ($ref in $Reflist){



[System.Runtime.InteropServices.Marshal]::ReleaseComObject([System.__ComObject]$ref) | out-null

[Runtime.InteropServices.Marshal]::FinalReleaseComObject($ref) | out-null

Remove-Variable $ref | out-null

}


[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()

}

Будет ли переменная Remove работать так, как я ожидал? Есть ли вред включению [System.GC] :: Collect ()?

1 Ответ

1 голос
/ 03 марта 2020

Да, и нет ... так как ...

[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()

... это обычная и лучшая практика.

Windows всегда будет выполнять очистку, но это всегда очищает вашу среду, когда вы закончите.

Как задокументировано ...

Очистите вашу среду PowerShell путем отслеживания переменных Использование https://devblogs.microsoft.com/scripting/clean-up-your-powershell-environment-by-tracking-variable-use

И подпадает под эти вопросы и ответы и принимает ответ ...

COM-объект релиза PowerShell

function Release-Ref ($ref) {

[System.Runtime.InteropServices.Marshal]::ReleaseComObject([System.__ComObject]$ref) | out-null
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()

}
because I've noted that my comobject always stay alive, I think Powershell 2.0 is not able to remove comobject no more used.

[System.Runtime.InteropServices.Marshal]::ReleaseComObject( $ref )

и это именно то, что вы спрашиваете, так что этот вопрос действительно дубликат.

В моем примере я использую префикс для моей переменной, чтобы их было легко найти и просто в глобальном масштабе убирать.

# Assign results to a variable and output to the screen using variable squeezing
($ponMyShell = New-Object -com "Wscript.Shell")
($ponDate = Get-Date)
($ponProcess = Get-Process |
    Select -First 3)

<#
# Results

Monday, 2 March, 2020 19:40:47

Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName                                                                                                              
-------  ------    -----      -----     ------     --  -- -----------                                                                                                              
    186      14     2648       6800       0.14  15336   0 aesm_service                                                                                                             
    465      27    24300      34064       0.33  27612  22 ApplicationFrameHost                                                                                                     
    158       8     1928       4848       0.02  14268   0 AppVShNotify 

SpecialFolders     CurrentDirectory   
--------------     ----------------   
System.__ComObject C:\Windows\system32
#>

Get-Variable -Name 'pon*'
<#
# Results 

Name                           Value                                                                                                                                               
----                           -----                                                                                                                                               
ponDate                        02-Mar-20 19:46:59                                                                                                                                  
ponMyShell                     System.__ComObject                                                                                                                                  
ponProcess                     {System.Diagnostics.Process (aesm_service), System.Diagnostics.Process (ApplicationFrameHost), System.Diagnostics.Process (AppVShNotify)} 
#>


# Clear resource environment
Get-PSSession |
Remove-PSSession
<#
# Results

#>

[System.Runtime.InteropServices.Marshal]::
ReleaseComObject([System.__ComObject]$ponMyShell) |
Out-Null
<#
# Results

#>

[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
<#
# Results

#>

Get-Variable -Name 'pon*' |
ForEach { Get-Variable -Name $_ |
    Remove-Variable -Force }

# Validate clean-up
Get-Variable -Name 'pon*'

<#
# Results


#>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...