如何利用Powershell脚本释放Windows内存

Leaphy 发布于 2024-08-09 最后更新于 20 天前 3,023 次阅读


AI 摘要

这篇文章介绍如何使用PowerShell脚本释放Windows内存,特别是在内存较少的云服务器上。文中提供了一个脚本,调用Windows API中的EmptyWorkingSet函数,遍历并释放每个进程的工作集,以降低内存占用。作者将C#代码嵌入PowerShell中,以定义新的.NET类型来实现功能。脚本执行后可以帮助清理内存,并触发垃圾回收以释放未使用的内存。尽管该方法有效,但作者建议使用像memreduct这样的内存清理工具可能效果更佳。

云服务器【1】一共就2GB内存,但因为要用RDP【2】硬装了 Windows Server【3】 (真是为难它了),内存占用常年70%+。研究了半天,发现用 powershell【4】 调用系统API【5】来释放内存资源是可行的。

Code:

下面的powershell脚本调用使用 Windows API 的 EmptyWorkingSet【6】函数,遍历释放每个进程【7】的工作集【8】

#Windows memory release powershell script.
#author:    Leau_0046
#version:   1.0
#date:      2024/8/9 11:10


# Set console output encoding to UTF-8 to ensure proper display
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
Add-Type @"
using System;
using System.Runtime.InteropServices;

public class PsAPI {
    [DllImport("psapi.dll")]
    public static extern int EmptyWorkingSet(IntPtr hwProc);
}
"@

function Clear-ProcessWorkingSet {
    $processes = Get-Process
    foreach ($process in $processes) {
        # Check if the handle is valid and not null
        if ($process.Handle -ne [IntPtr]::Zero -and $process.Handle) {
            try {
                # Call the Windows API's EmptyWorkingSet to free memory
                [PsAPI]::EmptyWorkingSet($process.Handle) | Out-Null
                Write-Host "Cleared working set for Process ID $($process.Id), Name $($process.Name)"
            } catch [System.Management.Automation.MethodInvocationException] {
                Write-Host "Method invocation error for Process ID $($process.Id): $_"
            } catch {
                Write-Host "Other error for Process ID $($process.Id): $_"
            }
        } else {
            Write-Host "Skipped invalid handle for Process ID $($process.Id), Name $($process.Name)"
        }
    }
}

# Call the function to clear memory
Clear-ProcessWorkingSet

# Trigger garbage collection to free unused memory
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
[System.GC]::Collect()

食用方法

  • 将上述代码保存为 .ps1 文件。
  • 右键点击“使用Powershell运行”

效果

Before:

After:

效果可能因机器而异。

解释

Add-Type:将 C# 代码嵌入到 PowerShell 中,并编译为一个新的 .NET 类型。

在这里,定义了一个调用 psapi.dll【9】 中的 EmptyWorkingSet函数的类。

写在最后的话

这只是一种解决方案,更推荐使用memreduct【10】一类的内存清理工具。效果应该会比这更好。