-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRAMOptimizer.ps1
342 lines (291 loc) · 13.6 KB
/
RAMOptimizer.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
# RAM Optimizer Script v3.2
# Requires administrative privileges to run
# Enable strict mode for better error handling
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
# Add Windows Forms for system tray icon
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
# Create system tray icon
$sysTrayIcon = New-Object System.Windows.Forms.NotifyIcon
$sysTrayIcon.Text = "RAM Optimizer"
$sysTrayIcon.Icon = [System.Drawing.SystemIcons]::Application
$sysTrayIcon.Visible = $true
# Create context menu
$contextMenu = New-Object System.Windows.Forms.ContextMenuStrip
$toolStripForceOptimize = New-Object System.Windows.Forms.ToolStripMenuItem
$toolStripForceOptimize.Text = "Force Optimization"
$toolStripExit = New-Object System.Windows.Forms.ToolStripMenuItem
$toolStripExit.Text = "Exit"
$contextMenu.Items.Add($toolStripForceOptimize)
$contextMenu.Items.Add($toolStripExit)
$sysTrayIcon.ContextMenuStrip = $contextMenu
# Function to show balloon tip
function Show-Notification {
param (
[string]$Title,
[string]$Message,
[System.Windows.Forms.ToolTipIcon]$Icon = [System.Windows.Forms.ToolTipIcon]::Info
)
$sysTrayIcon.BalloonTipTitle = $Title
$sysTrayIcon.BalloonTipText = $Message
$sysTrayIcon.BalloonTipIcon = $Icon
$sysTrayIcon.ShowBalloonTip(5000)
}
# Check for Admin privileges
$isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
if (-not $isAdmin) {
Write-Host "This script requires Administrator privileges. Please run as Administrator." -ForegroundColor Red
Exit 1
}
# Import required assemblies
Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;
public class MemoryManagement {
[DllImport("kernel32.dll")]
public static extern bool SetProcessWorkingSetSize(IntPtr proc, int min, int max);
[DllImport("psapi.dll")]
public static extern bool EmptyWorkingSet(IntPtr hProcess);
[DllImport("kernel32.dll")]
public static extern bool SetSystemFileCacheSize(int MinimumFileCacheSize, int MaximumFileCacheSize, int Flags);
}
"@
# Function to get detailed system memory information
function Get-MemoryDetails {
try {
$os = Get-CimInstance Win32_OperatingSystem
$cs = Get-CimInstance Win32_ComputerSystem
$totalRAM = [math]::Round($cs.TotalPhysicalMemory / 1GB, 2)
$freeRAM = [math]::Round($os.FreePhysicalMemory / 1KB / 1024, 2)
$usedRAM = [math]::Round($totalRAM - $freeRAM, 2)
$ramUsage = [math]::Round(($usedRAM / $totalRAM) * 100, 2)
return @{
TotalRAM = $totalRAM
FreeRAM = $freeRAM
UsedRAM = $usedRAM
UsagePercent = $ramUsage
PageFileUsage = [math]::Round(($os.SizeStoredInPagingFiles - $os.FreeSpaceInPagingFiles) / 1MB, 2)
CommittedMemory = [math]::Round($os.TotalVirtualMemorySize / 1MB, 2)
}
} catch {
Write-Host "Error getting memory details: $($_.Exception.Message)" -ForegroundColor Red
throw
}
}
# Function to get top memory-consuming processes with more details
function Get-TopMemoryProcesses {
return Get-Process |
Where-Object { -not [string]::IsNullOrEmpty($_.ProcessName) } |
Sort-Object WorkingSet64 -Descending |
Select-Object -First 8 Name,
@{Name='PID';Expression={$_.Id}},
@{Name='Memory(MB)';Expression={[math]::Round($_.WorkingSet64 / 1MB, 2)}},
@{Name='Private(MB)';Expression={[math]::Round($_.PrivateMemorySize64 / 1MB, 2)}},
@{Name='CPU(s)';Expression={[math]::Round($_.CPU, 2)}},
@{Name='ThreadCount';Expression={$_.Threads.Count}},
@{Name='Handles';Expression={$_.HandleCount}}
}
# Function to optimize specific process memory
function Optimize-ProcessMemory {
param (
[Parameter(Mandatory=$true)]
[int]$processId,
[switch]$Aggressive
)
try {
$process = Get-Process -Id $processId -ErrorAction Stop
if ($process.ProcessName -notin @('System', 'Idle', 'Registry')) {
[MemoryManagement]::EmptyWorkingSet($process.Handle) | Out-Null
if ($Aggressive) {
[MemoryManagement]::SetProcessWorkingSetSize($process.Handle, -1, -1) | Out-Null
}
return $true
}
} catch {
return $false
}
}
# Function to clear system caches
function Clear-SystemCaches {
param([switch]$Aggressive)
try {
# Clear file system cache
Write-Host "Clearing file system cache..."
[MemoryManagement]::SetSystemFileCacheSize(0, 0, 0) | Out-Null
# Clear DNS cache
Write-Host "Clearing DNS cache..."
Start-Process "ipconfig" -ArgumentList "/flushdns" -WindowStyle Hidden -Wait
if ($Aggressive) {
# Clear additional caches
Write-Host "Clearing additional system caches..."
$commands = @(
"netsh interface ip delete arpcache",
"netsh winsock reset",
"sc stop sysmain", # Disable Superfetch
"sc config sysmain start= disabled"
)
foreach ($cmd in $commands) {
Start-Process "cmd.exe" -ArgumentList "/c $cmd" -WindowStyle Hidden -Wait
}
}
# Clear temp files
$tempPaths = @(
"$env:TEMP",
"$env:SystemRoot\Temp",
"$env:USERPROFILE\AppData\Local\Temp",
"$env:SystemRoot\Prefetch",
"$env:USERPROFILE\AppData\Local\Microsoft\Windows\INetCache"
)
foreach ($path in $tempPaths) {
if (Test-Path $path) {
Get-ChildItem -Path $path -File -Force |
Where-Object { -not $_.PSIsContainer -and $_.LastWriteTime -lt (Get-Date).AddDays(-1) } |
Remove-Item -Force -ErrorAction SilentlyContinue
}
}
return $true
} catch {
Write-Host "Error clearing system caches: $($_.Exception.Message)" -ForegroundColor Red
return $false
}
}
# Function to optimize RAM
function Optimize-RAM {
param ([switch]$Aggressive)
$startTime = Get-Date
Write-Host "`n[$(Get-Date)] Starting RAM optimization..." -ForegroundColor Yellow
Show-Notification "RAM Optimization" "Starting memory optimization..."
try {
# Get initial memory state
$initialMemory = Get-MemoryDetails
# Display system memory status
Write-Host "`nSystem Memory Status:" -ForegroundColor Cyan
Write-Host "Total RAM: $($initialMemory.TotalRAM) GB"
Write-Host "Used RAM: $($initialMemory.UsedRAM) GB"
Write-Host "Free RAM: $($initialMemory.FreeRAM) GB"
Write-Host "Page File Usage: $($initialMemory.PageFileUsage) MB"
# Display top memory-consuming processes
Write-Host "`nTop memory-consuming processes before optimization:" -ForegroundColor Cyan
Get-TopMemoryProcesses | Format-Table -AutoSize
# Optimize processes
Write-Host "Optimizing process memory..."
$optimizedCount = 0
Get-Process | Where-Object { $_.WorkingSet64 -gt 100MB } | ForEach-Object {
if (Optimize-ProcessMemory -processId $_.Id -Aggressive:$Aggressive) {
Write-Host "Optimized: $($_.ProcessName) (PID: $($_.Id))" -ForegroundColor DarkGray
$optimizedCount++
}
}
# Clear system caches
Clear-SystemCaches -Aggressive:$Aggressive
# Run garbage collection
[System.GC]::Collect(2, [System.GCCollectionMode]::Forced, $true, $true)
[System.GC]::WaitForPendingFinalizers()
# Get final memory state
Start-Sleep -Seconds 2 # Wait for changes to take effect
$finalMemory = Get-MemoryDetails
$freedMemory = $initialMemory.UsedRAM - $finalMemory.UsedRAM
$improvement = $initialMemory.UsagePercent - $finalMemory.UsagePercent
$duration = (Get-Date) - $startTime
# Display results with notification
$resultMessage = "Memory freed: $($freedMemory.ToString('0.00')) GB`nImprovement: $($improvement.ToString('0.00'))%"
Show-Notification "Optimization Complete" $resultMessage
Write-Host "`nOptimization Results:" -ForegroundColor Green
Write-Host "Duration: $($duration.TotalSeconds.ToString('0.00')) seconds"
Write-Host "Processes Optimized: $optimizedCount"
Write-Host "Initial RAM Usage: $($initialMemory.UsagePercent)%" -ForegroundColor Yellow
Write-Host "Final RAM Usage: $($finalMemory.UsagePercent)%" -ForegroundColor Yellow
Write-Host "Memory Freed: $($freedMemory.ToString('0.00')) GB" -ForegroundColor Green
Write-Host "Improvement: $($improvement.ToString('0.00'))%" -ForegroundColor Green
Write-Host "`nCurrent top memory-consuming processes:" -ForegroundColor Cyan
Get-TopMemoryProcesses | Format-Table -AutoSize
} catch {
$errorMsg = "Error during optimization: $($_.Exception.Message)"
Write-Host $errorMsg -ForegroundColor Red
Write-Host $_.ScriptStackTrace -ForegroundColor DarkRed
Show-Notification "Optimization Error" $errorMsg ([System.Windows.Forms.ToolTipIcon]::Error)
}
Write-Host "`nRAM optimization cycle completed!" -ForegroundColor Green
Write-Host "----------------------------------------`n"
}
# Configuration
$config = @{
ThresholdNormal = 70 # Normal threshold (%)
ThresholdHigh = 85 # High threshold for aggressive mode (%)
CheckInterval = 30 # Check every 30 seconds
CooldownNormal = 300 # 5 minutes cooldown for normal optimization
CooldownAggressive = 600 # 10 minutes cooldown for aggressive optimization
LogFile = "$env:USERPROFILE\Documents\RAMOptimizer.log"
MaxLogSize = 10MB # Maximum log file size
}
# Initialize logging
if (-not (Test-Path $config.LogFile)) {
New-Item -Path $config.LogFile -ItemType File -Force | Out-Null
}
# Rotate log if too large
if ((Get-Item $config.LogFile).Length -gt $config.MaxLogSize) {
Move-Item -Path $config.LogFile -Destination "$($config.LogFile).old" -Force
}
$lastOptimizationTime = [DateTime]::MinValue
$script:lastRAMUsage = 0
# Display startup information
Write-Host "RAM Optimizer v3.2 Started" -ForegroundColor Cyan
Write-Host "----------------------------------------"
Write-Host "Normal Threshold: $($config.ThresholdNormal)%"
Write-Host "Aggressive Threshold: $($config.ThresholdHigh)%"
Write-Host "Check Interval: $($config.CheckInterval) seconds"
Write-Host "Normal Cooldown: $($config.CooldownNormal / 60) minutes"
Write-Host "Aggressive Cooldown: $($config.CooldownAggressive / 60) minutes"
Write-Host "Log File: $($config.LogFile)"
Write-Host "----------------------------------------`n"
# Register event handlers
$toolStripForceOptimize.Add_Click({
Write-Host "Manual optimization requested by user"
Optimize-RAM -Aggressive
})
$toolStripExit.Add_Click({
$sysTrayIcon.Visible = $false
$sysTrayIcon.Dispose()
Stop-Process $pid
})
# Show startup notification
Show-Notification "RAM Optimizer Started" "Monitoring RAM usage. Normal threshold: $($config.ThresholdNormal)%"
# Main monitoring loop with UI message pump
[System.Windows.Forms.Application]::EnableVisualStyles()
$appContext = New-Object System.Windows.Forms.ApplicationContext
while ($true) {
try {
[System.Windows.Forms.Application]::DoEvents()
$memInfo = Get-MemoryDetails
$currentRAMUsage = $memInfo.UsagePercent
$script:lastRAMUsage = $currentRAMUsage
$timeSinceLastOptimization = (Get-Date) - $lastOptimizationTime
# Update system tray icon tooltip
$sysTrayIcon.Text = "RAM Usage: $($currentRAMUsage)%`nFree: $($memInfo.FreeRAM) GB"
# Log current status
$status = "RAM Usage: $currentRAMUsage% | Free: $($memInfo.FreeRAM) GB | Used: $($memInfo.UsedRAM) GB | $(Get-Date -Format 'HH:mm:ss')"
Write-Host $status -ForegroundColor Gray
Add-Content -Path $config.LogFile -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss'): $status"
# Check if optimization is needed
if ($currentRAMUsage -ge $config.ThresholdHigh -and $timeSinceLastOptimization.TotalSeconds -ge $config.CooldownAggressive) {
Write-Host "Critical RAM usage detected! ($currentRAMUsage%)" -ForegroundColor Red
Show-Notification "Critical RAM Usage" "RAM usage is at $currentRAMUsage%. Starting aggressive optimization..." ([System.Windows.Forms.ToolTipIcon]::Warning)
Optimize-RAM -Aggressive
$lastOptimizationTime = Get-Date
}
elseif ($currentRAMUsage -ge $config.ThresholdNormal -and $timeSinceLastOptimization.TotalSeconds -ge $config.CooldownNormal) {
Write-Host "High RAM usage detected! ($currentRAMUsage%)" -ForegroundColor Yellow
Show-Notification "High RAM Usage" "RAM usage is at $currentRAMUsage%. Starting optimization..."
Optimize-RAM
$lastOptimizationTime = Get-Date
}
Start-Sleep -Seconds $config.CheckInterval
} catch {
$errorMessage = "Error in main loop: $($_.Exception.Message)"
Write-Host $errorMessage -ForegroundColor Red
Add-Content -Path $config.LogFile -Value "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss'): ERROR - $errorMessage"
Show-Notification "Error" $errorMessage ([System.Windows.Forms.ToolTipIcon]::Error)
Start-Sleep -Seconds 10
}
}