Skip to content

Commit a578a36

Browse files
committed
* Added the DateTime at which an ErrorLog was added
* Look out for doubles being cast as infinite or NaN * Added the ability to clear RAM by filling it up. Paradoxical, I know * Minor design changes
1 parent 5cd0ebd commit a578a36

File tree

18 files changed

+225
-55
lines changed

18 files changed

+225
-55
lines changed

MemPlus/App.config

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,12 @@
153153
<setting name="RamMaxUsageHistoryCount" serializeAs="String">
154154
<value>100</value>
155155
</setting>
156+
<setting name="FillRam" serializeAs="String">
157+
<value>True</value>
158+
</setting>
159+
<setting name="FillRamMaxRuns" serializeAs="String">
160+
<value>1</value>
161+
</setting>
156162
</MemPlus.Properties.Settings>
157163
</userSettings>
158164
<runtime>

MemPlus/Business/LOG/ErrorLog.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using System;
2+
13
namespace MemPlus.Business.LOG
24
{
35
internal sealed class ErrorLog : Log
@@ -11,6 +13,7 @@ internal ErrorLog(string data)
1113
{
1214
LogType = LogType.Error;
1315
Data = data;
16+
Time = DateTime.Now;
1417
}
1518
}
1619
}

MemPlus/Business/RAM/RamController.cs

Lines changed: 86 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,14 @@ internal sealed class RamController : IDisposable
9494
/// Property displaying whether the .NET garbage collector should be invoked or not
9595
/// </summary>
9696
internal bool InvokeGarbageCollector { private get; set; }
97+
/// <summary>
98+
/// Property displaying whether RAM memory should be completely filled or not
99+
/// </summary>
100+
internal bool FillRam { get; set; }
101+
/// <summary>
102+
/// The amount of times the FillRam method should run
103+
/// </summary>
104+
internal int FillRamMaxRuns { private get; set; }
97105
#endregion
98106

99107
#region Delegates
@@ -235,7 +243,14 @@ internal void EnableMonitor()
235243
_ramTimer.Enabled = true;
236244
RamMonitorEnabled = true;
237245

238-
UpdateRamUsage();
246+
try
247+
{
248+
UpdateRamUsage();
249+
}
250+
catch (Exception ex)
251+
{
252+
_logController.AddLog(new ErrorLog(ex.Message));
253+
}
239254

240255
_logController.AddLog(new ApplicationLog("The RAM monitor has been enabled"));
241256
}
@@ -260,7 +275,14 @@ private void OnTimedEvent(object source, ElapsedEventArgs e)
260275
{
261276
_logController.AddLog(new ApplicationLog("RAM monitor timer has been called"));
262277

263-
UpdateRamUsage();
278+
try
279+
{
280+
UpdateRamUsage();
281+
}
282+
catch (Exception ex)
283+
{
284+
_logController.AddLog(new ErrorLog(ex.Message));
285+
}
264286

265287
_logController.AddLog(new ApplicationLog("Finished RAM monitor timer"));
266288
}
@@ -276,32 +298,44 @@ internal async Task ClearMemory()
276298

277299
await Task.Run(async () =>
278300
{
279-
UpdateRamUsage();
301+
try
302+
{
303+
UpdateRamUsage();
280304

281-
double oldUsage = _ramUsageHistory[_ramUsageHistory.Count - 1].TotalUsed;
305+
double oldUsage = _ramUsageHistory[_ramUsageHistory.Count - 1].TotalUsed;
282306

283-
if (EmptyWorkingSets)
284-
{
285-
_ramOptimizer.EmptyWorkingSetFunction(_processExceptionList);
286-
await Task.Delay(10000);
287-
}
307+
if (FillRam)
308+
{
309+
_ramOptimizer.FillRam(_info, FillRamMaxRuns);
310+
}
288311

289-
if (ClearFileSystemCache)
290-
{
291-
_ramOptimizer.ClearFileSystemCache(ClearStandbyCache);
292-
}
312+
if (EmptyWorkingSets)
313+
{
314+
_ramOptimizer.EmptyWorkingSetFunction(_processExceptionList);
315+
await Task.Delay(10000);
316+
}
293317

294-
if (InvokeGarbageCollector)
295-
{
296-
GC.Collect();
297-
GC.WaitForPendingFinalizers();
298-
}
318+
if (ClearFileSystemCache)
319+
{
320+
_ramOptimizer.ClearFileSystemCache(ClearStandbyCache);
321+
}
299322

300-
UpdateRamUsage();
323+
if (InvokeGarbageCollector)
324+
{
325+
GC.Collect();
326+
GC.WaitForPendingFinalizers();
327+
}
301328

302-
double newUsage = _ramUsageHistory[_ramUsageHistory.Count - 1].TotalUsed;
329+
UpdateRamUsage();
303330

304-
RamSavings = oldUsage - newUsage;
331+
double newUsage = _ramUsageHistory[_ramUsageHistory.Count - 1].TotalUsed;
332+
333+
RamSavings = oldUsage - newUsage;
334+
}
335+
catch (Exception ex)
336+
{
337+
_logController.AddLog(new ErrorLog(ex.Message));
338+
}
305339
});
306340

307341
if (ClearClipboard)
@@ -324,19 +358,26 @@ internal async Task ClearWorkingSets()
324358

325359
await Task.Run(async () =>
326360
{
327-
UpdateRamUsage();
361+
try
362+
{
363+
UpdateRamUsage();
328364

329-
double oldUsage = _ramUsageHistory[_ramUsageHistory.Count - 1].TotalUsed;
365+
double oldUsage = _ramUsageHistory[_ramUsageHistory.Count - 1].TotalUsed;
330366

331-
_ramOptimizer.EmptyWorkingSetFunction(_processExceptionList);
367+
_ramOptimizer.EmptyWorkingSetFunction(_processExceptionList);
332368

333-
await Task.Delay(10000);
369+
await Task.Delay(10000);
334370

335-
UpdateRamUsage();
371+
UpdateRamUsage();
336372

337-
double newUsage = _ramUsageHistory[_ramUsageHistory.Count - 1].TotalUsed;
373+
double newUsage = _ramUsageHistory[_ramUsageHistory.Count - 1].TotalUsed;
338374

339-
RamSavings = oldUsage - newUsage;
375+
RamSavings = oldUsage - newUsage;
376+
}
377+
catch (Exception ex)
378+
{
379+
_logController.AddLog(new ErrorLog(ex.Message));
380+
}
340381
});
341382

342383
RamClearingCompletedEvent?.Invoke();
@@ -354,17 +395,24 @@ internal async Task ClearFileSystemCaches()
354395

355396
await Task.Run(() =>
356397
{
357-
UpdateRamUsage();
398+
try
399+
{
400+
UpdateRamUsage();
358401

359-
double oldUsage = _ramUsageHistory[_ramUsageHistory.Count - 1].TotalUsed;
402+
double oldUsage = _ramUsageHistory[_ramUsageHistory.Count - 1].TotalUsed;
360403

361-
_ramOptimizer.ClearFileSystemCache(ClearStandbyCache);
404+
_ramOptimizer.ClearFileSystemCache(ClearStandbyCache);
362405

363-
UpdateRamUsage();
406+
UpdateRamUsage();
364407

365-
double newUsage = _ramUsageHistory[_ramUsageHistory.Count - 1].TotalUsed;
408+
double newUsage = _ramUsageHistory[_ramUsageHistory.Count - 1].TotalUsed;
366409

367-
RamSavings = oldUsage - newUsage;
410+
RamSavings = oldUsage - newUsage;
411+
}
412+
catch (Exception ex)
413+
{
414+
_logController.AddLog(new ErrorLog(ex.Message));
415+
}
368416
});
369417

370418
RamClearingCompletedEvent?.Invoke();
@@ -383,6 +431,10 @@ private void UpdateRamUsage()
383431
double usage = total - Convert.ToDouble(_info.AvailablePhysicalMemory);
384432
double percentage = usage / total * 100;
385433

434+
if (double.IsNaN(total) || double.IsInfinity(total)) throw new ArgumentException(nameof(total));
435+
if (double.IsNaN(usage) || double.IsInfinity(usage)) throw new ArgumentException(nameof(usage));
436+
if (double.IsNaN(percentage) || double.IsInfinity(percentage)) throw new ArgumentException(nameof(percentage));
437+
386438
RamUsage newUsage = new RamUsage(usage, total, percentage);
387439
if (EnableRamStatistics)
388440
{

MemPlus/Business/RAM/RamOptimizer.cs

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Security.Principal;
77
using MemPlus.Business.LOG;
88
using MemPlus.Business.UTILS;
9+
using Microsoft.VisualBasic.Devices;
910

1011
namespace MemPlus.Business.RAM
1112
{
@@ -255,7 +256,7 @@ internal void ClearFileSystemCache(bool clearStandbyCache)
255256
_logController.AddLog(new ErrorLog(ex.ToString()));
256257
}
257258
}
258-
259+
259260
/// <summary>
260261
/// Increase the Privilege using a privilege name
261262
/// </summary>
@@ -267,25 +268,74 @@ private bool SetIncreasePrivilege(string privilegeName)
267268

268269
using (WindowsIdentity current = WindowsIdentity.GetCurrent(TokenAccessLevels.Query | TokenAccessLevels.AdjustPrivileges))
269270
{
270-
TokenPrivileges newst;
271-
newst.Count = 1;
272-
newst.Luid = 0L;
273-
newst.Attr = PrivilegeEnabled;
271+
TokenPrivileges tokenPrivileges;
272+
tokenPrivileges.Count = 1;
273+
tokenPrivileges.Luid = 0L;
274+
tokenPrivileges.Attr = PrivilegeEnabled;
274275

275276
_logController.AddLog(new RamLog("Looking up privilege value"));
276277
// If we can't look up the privilege value, we can't function properly
277-
if (!NativeMethods.LookupPrivilegeValue(null, privilegeName, ref newst.Luid)) throw new Exception("LookupPrivilegeValue: ", new Win32Exception(Marshal.GetLastWin32Error()));
278+
if (!NativeMethods.LookupPrivilegeValue(null, privilegeName, ref tokenPrivileges.Luid)) throw new Exception("LookupPrivilegeValue: ", new Win32Exception(Marshal.GetLastWin32Error()));
278279
_logController.AddLog(new RamLog("Done looking up privilege value"));
279280

280281

281282
_logController.AddLog(new RamLog("Adjusting token privileges"));
282283
// Enables or disables privileges in a specified access token
283-
int adjustTokenPrivilegesRet = NativeMethods.AdjustTokenPrivileges(current.Token, false, ref newst, 0, IntPtr.Zero, IntPtr.Zero) ? 1 : 0;
284+
int adjustTokenPrivilegesRet = NativeMethods.AdjustTokenPrivileges(current.Token, false, ref tokenPrivileges, 0, IntPtr.Zero, IntPtr.Zero) ? 1 : 0;
284285
// Return value of zero indicates an error
285286
if (adjustTokenPrivilegesRet == 0) throw new Exception("AdjustTokenPrivileges: ", new Win32Exception(Marshal.GetLastWin32Error()));
286287
_logController.AddLog(new RamLog("Done adjusting token privileges"));
287288
return adjustTokenPrivilegesRet != 0;
288289
}
289290
}
291+
292+
/// <summary>
293+
/// Fill the available RAM
294+
/// </summary>
295+
/// <param name="info">The ComputerInfo object that can be used to calculate usage percentages</param>
296+
/// <param name="maxRuns">The amount of times the RAM should be filled</param>
297+
internal void FillRam(ComputerInfo info, int maxRuns)
298+
{
299+
_logController.AddLog(new RamLog("Attempting to fill the available RAM"));
300+
int runs = 0;
301+
while (runs < maxRuns)
302+
{
303+
List<IntPtr> pointers = new List<IntPtr>();
304+
// Don't keep calling the info object because this can cause a Win32Exception
305+
double total = Convert.ToDouble(info.TotalPhysicalMemory);
306+
double usage = total - Convert.ToDouble(info.AvailablePhysicalMemory);
307+
double percentage = usage / total * 100;
308+
309+
if (double.IsNaN(total) || double.IsInfinity(total)) throw new ArgumentException(nameof(total));
310+
if (double.IsNaN(usage) || double.IsInfinity(usage)) throw new ArgumentException(nameof(usage));
311+
if (double.IsNaN(percentage) || double.IsInfinity(percentage)) throw new ArgumentException(nameof(percentage));
312+
313+
// 99 is the threshold for the amount of RAM that should be filled
314+
// Windows will do its best to manage the available memory while its filling up
315+
while (percentage < 99)
316+
{
317+
IntPtr pointer = Marshal.AllocHGlobal(1024);
318+
pointers.Add(pointer);
319+
320+
usage += 1024;
321+
percentage = usage / total * 100;
322+
}
323+
324+
foreach (IntPtr clearPtr in pointers)
325+
{
326+
try
327+
{
328+
// Clean all previously acquired IntPtr objects pointing to the allocated memory
329+
Marshal.FreeHGlobal(clearPtr);
330+
}
331+
catch (Exception ex)
332+
{
333+
_logController.AddLog(new ErrorLog(ex.Message));
334+
}
335+
}
336+
runs++;
337+
}
338+
_logController.AddLog(new RamLog("Done filling available RAM"));
339+
}
290340
}
291341
}

MemPlus/Business/UTILS/GridViewSort.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,7 @@ internal static void SetEnabled(DependencyObject obj, bool value)
4242
(o, e) =>
4343
{
4444
// ReSharper disable once UsePatternMatching
45-
ListView listView = o as ListView;
46-
if (listView == null) return;
45+
if (!(o is ListView listView)) return;
4746
bool oldValue = (bool)e.OldValue;
4847
bool newValue = (bool)e.NewValue;
4948
if (oldValue && !newValue)

MemPlus/Properties/Settings.Designer.cs

Lines changed: 25 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

MemPlus/Properties/Settings.settings

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,5 +147,11 @@
147147
<Setting Name="RamMaxUsageHistoryCount" Type="System.Int32" Scope="User">
148148
<Value Profile="(Default)">100</Value>
149149
</Setting>
150+
<Setting Name="FillRam" Type="System.Boolean" Scope="User">
151+
<Value Profile="(Default)">True</Value>
152+
</Setting>
153+
<Setting Name="FillRamMaxRuns" Type="System.Int32" Scope="User">
154+
<Value Profile="(Default)">1</Value>
155+
</Setting>
150156
</Settings>
151157
</SettingsFile>

MemPlus/Resources/Languages/ar_SA.xaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@
130130
<system:String x:Key="EnableRamStatistics">RAM تمكين إحصائيات</system:String>
131131
<system:String x:Key="RamStatisticsCount">إحصائيات RAM الحد الأقصى لعدد</system:String>
132132
<system:String x:Key="RamStatisticsCountHint">RAM اضبط على الصفر في حالة عدم إزالة إحصائيات</system:String>
133+
<system:String x:Key="FillRam">RAM ملء</system:String>
134+
<system:String x:Key="FillRamMaxRunsHint">مقدار المرات التي يجب فيها ملء ذاكرة الوصول العشوائي</system:String>
133135

134136
<!-- Automatic translation - Needs translation -->
135137
<system:String x:Key="LogSettings">تسجيل</system:String>

MemPlus/Resources/Languages/de_DE.xaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@
131131
<system:String x:Key="EnableRamStatistics">Aktivieren Sie die RAM-Statistik</system:String>
132132
<system:String x:Key="RamStatisticsCount">RAM Statistik maximale Anzahl:</system:String>
133133
<system:String x:Key="RamStatisticsCountHint">Auf null setzen, wenn RAM-Statistiken niemals entfernt werden sollen</system:String>
134+
<system:String x:Key="FillRam">RAM füllen</system:String>
135+
<system:String x:Key="FillRamMaxRunsHint">Die Anzahl der Male, die der RAM gefüllt werden muss</system:String>
134136

135137
<system:String x:Key="LogSettings">Protokollierung</system:String>
136138
<system:String x:Key="LoggingEnabled">Protokollierung aktiviert</system:String>

0 commit comments

Comments
 (0)