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

Leaphy 发布于 2024-08-09 最后更新于 2025-02-02 2,270 次阅读


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

Code:

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

#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 中的 EmptyWorkingSet函数的类。

写在最后的话

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