1
0
mirror of https://github.com/chylex/TweetDuck.git synced 2025-04-17 12:15:47 +02:00

Add a WIP memory tracker that runs GC reload, and fix config

This commit is contained in:
chylex 2017-07-04 22:00:03 +02:00
parent d77de3bb12
commit 4d77a498f6
6 changed files with 180 additions and 36 deletions

View File

@ -19,7 +19,7 @@ public override Type BindToType(string assemblyName, string typeName){
} }
} }
private const int CurrentFileVersion = 11; private const int CurrentFileVersion = 12;
// START OF CONFIGURATION // START OF CONFIGURATION
@ -202,6 +202,9 @@ private void UpgradeFile(){
if (fileVersion == 10){ if (fileVersion == 10){
NotificationSize = TweetNotification.Size.Auto; NotificationSize = TweetNotification.Size.Auto;
}
if (fileVersion == 11){
BrowserMemoryThreshold = 350; BrowserMemoryThreshold = 350;
++fileVersion; ++fileVersion;
} }

View File

@ -32,6 +32,7 @@ sealed partial class FormBrowser : Form{
private readonly UpdateHandler updates; private readonly UpdateHandler updates;
private readonly FormNotificationTweet notification; private readonly FormNotificationTweet notification;
private readonly ContextMenu contextMenu; private readonly ContextMenu contextMenu;
private readonly MemoryUsageTracker memoryUsageTracker;
private bool isLoaded; private bool isLoaded;
private bool isBrowserReady; private bool isBrowserReady;
@ -50,6 +51,7 @@ public FormBrowser(PluginManager pluginManager, UpdaterSettings updaterSettings)
this.plugins.PluginChangedState += plugins_PluginChangedState; this.plugins.PluginChangedState += plugins_PluginChangedState;
this.contextMenu = ContextMenuBrowser.CreateMenu(this); this.contextMenu = ContextMenuBrowser.CreateMenu(this);
this.memoryUsageTracker = new MemoryUsageTracker("TDGF_tryRunCleanup");
this.notification = new FormNotificationTweet(this, plugins){ this.notification = new FormNotificationTweet(this, plugins){
#if DEBUG #if DEBUG
@ -87,6 +89,8 @@ public FormBrowser(PluginManager pluginManager, UpdaterSettings updaterSettings)
Controls.Add(new MenuStrip{ Visible = false }); // fixes Alt freezing the program in Win 10 Anniversary Update Controls.Add(new MenuStrip{ Visible = false }); // fixes Alt freezing the program in Win 10 Anniversary Update
Disposed += (sender, args) => { Disposed += (sender, args) => {
memoryUsageTracker.Dispose();
browser.Dispose(); browser.Dispose();
contextMenu.Dispose(); contextMenu.Dispose();
@ -165,6 +169,8 @@ private void browser_LoadingStateChanged(object sender, LoadingStateChangedEvent
private void browser_FrameLoadStart(object sender, FrameLoadStartEventArgs e){ private void browser_FrameLoadStart(object sender, FrameLoadStartEventArgs e){
if (e.Frame.IsMain){ if (e.Frame.IsMain){
memoryUsageTracker.Stop();
if (Config.ZoomLevel != 100){ if (Config.ZoomLevel != 100){
BrowserUtils.SetZoomLevel(browser.GetBrowser(), Config.ZoomLevel); BrowserUtils.SetZoomLevel(browser.GetBrowser(), Config.ZoomLevel);
} }
@ -190,6 +196,10 @@ private void browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e){
} }
TweetDeckBridge.ResetStaticProperties(); TweetDeckBridge.ResetStaticProperties();
if (Config.EnableBrowserGCReload){
memoryUsageTracker.Start(this, e.Browser, Config.BrowserMemoryThreshold);
}
} }
} }
@ -424,6 +434,13 @@ public void OpenSettings(Type startTab){
if (!Config.EnableTrayHighlight){ if (!Config.EnableTrayHighlight){
trayIcon.HasNotifications = false; trayIcon.HasNotifications = false;
} }
if (Config.EnableBrowserGCReload){
memoryUsageTracker.Start(this, browser.GetBrowser(), Config.BrowserMemoryThreshold);
}
else{
memoryUsageTracker.Stop();
}
UpdateProperties(PropertyBridge.Properties.ExpandLinksOnHover | PropertyBridge.Properties.SwitchAccountSelectors | PropertyBridge.Properties.HasCustomNotificationSound); UpdateProperties(PropertyBridge.Properties.ExpandLinksOnHover | PropertyBridge.Properties.SwitchAccountSelectors | PropertyBridge.Properties.HasCustomNotificationSound);

View File

@ -24,7 +24,6 @@ protected override void Dispose(bool disposing) {
/// </summary> /// </summary>
private void InitializeComponent() { private void InitializeComponent() {
this.components = new System.ComponentModel.Container(); this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TabSettingsAdvanced));
this.btnClearCache = new System.Windows.Forms.Button(); this.btnClearCache = new System.Windows.Forms.Button();
this.checkHardwareAcceleration = new System.Windows.Forms.CheckBox(); this.checkHardwareAcceleration = new System.Windows.Forms.CheckBox();
this.toolTip = new System.Windows.Forms.ToolTip(this.components); this.toolTip = new System.Windows.Forms.ToolTip(this.components);
@ -35,17 +34,17 @@ private void InitializeComponent() {
this.btnOpenAppFolder = new System.Windows.Forms.Button(); this.btnOpenAppFolder = new System.Windows.Forms.Button();
this.btnOpenDataFolder = new System.Windows.Forms.Button(); this.btnOpenDataFolder = new System.Windows.Forms.Button();
this.checkBrowserGCReload = new System.Windows.Forms.CheckBox(); this.checkBrowserGCReload = new System.Windows.Forms.CheckBox();
this.numMemoryThreshold = new TweetDuck.Core.Controls.NumericUpDownEx();
this.labelApp = new System.Windows.Forms.Label(); this.labelApp = new System.Windows.Forms.Label();
this.panelApp = new System.Windows.Forms.Panel(); this.panelApp = new System.Windows.Forms.Panel();
this.labelPerformance = new System.Windows.Forms.Label(); this.labelPerformance = new System.Windows.Forms.Label();
this.panelPerformance = new System.Windows.Forms.Panel(); this.panelPerformance = new System.Windows.Forms.Panel();
this.numMemoryThreshold = new TweetDuck.Core.Controls.NumericUpDownEx();
this.labelMemoryUsage = new System.Windows.Forms.Label(); this.labelMemoryUsage = new System.Windows.Forms.Label();
this.panelConfiguration = new System.Windows.Forms.Panel(); this.panelConfiguration = new System.Windows.Forms.Panel();
this.labelConfiguration = new System.Windows.Forms.Label(); this.labelConfiguration = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.numMemoryThreshold)).BeginInit();
this.panelApp.SuspendLayout(); this.panelApp.SuspendLayout();
this.panelPerformance.SuspendLayout(); this.panelPerformance.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.numMemoryThreshold)).BeginInit();
this.panelConfiguration.SuspendLayout(); this.panelConfiguration.SuspendLayout();
this.SuspendLayout(); this.SuspendLayout();
// //
@ -147,9 +146,38 @@ private void InitializeComponent() {
this.checkBrowserGCReload.Size = new System.Drawing.Size(190, 17); this.checkBrowserGCReload.Size = new System.Drawing.Size(190, 17);
this.checkBrowserGCReload.TabIndex = 4; this.checkBrowserGCReload.TabIndex = 4;
this.checkBrowserGCReload.Text = "Enable Browser Memory Threshold"; this.checkBrowserGCReload.Text = "Enable Browser Memory Threshold";
this.toolTip.SetToolTip(this.checkBrowserGCReload, resources.GetString("checkBrowserGCReload.ToolTip"));
this.checkBrowserGCReload.UseVisualStyleBackColor = true; this.checkBrowserGCReload.UseVisualStyleBackColor = true;
// //
// numMemoryThreshold
//
this.numMemoryThreshold.Increment = new decimal(new int[] {
50,
0,
0,
0});
this.numMemoryThreshold.Location = new System.Drawing.Point(202, 82);
this.numMemoryThreshold.Maximum = new decimal(new int[] {
3000,
0,
0,
0});
this.numMemoryThreshold.Minimum = new decimal(new int[] {
200,
0,
0,
0});
this.numMemoryThreshold.Name = "numMemoryThreshold";
this.numMemoryThreshold.Size = new System.Drawing.Size(97, 20);
this.numMemoryThreshold.TabIndex = 3;
this.numMemoryThreshold.TextSuffix = " MB";
this.toolTip.SetToolTip(this.numMemoryThreshold, "Minimum amount of memory usage by the browser process to trigger the cleanup.\r\nTh" +
"is is not a limit, the usage is allowed to exceed this value.");
this.numMemoryThreshold.Value = new decimal(new int[] {
350,
0,
0,
0});
//
// labelApp // labelApp
// //
this.labelApp.AutoSize = true; this.labelApp.AutoSize = true;
@ -199,36 +227,6 @@ private void InitializeComponent() {
this.panelPerformance.Size = new System.Drawing.Size(322, 105); this.panelPerformance.Size = new System.Drawing.Size(322, 105);
this.panelPerformance.TabIndex = 3; this.panelPerformance.TabIndex = 3;
// //
// numMemoryThreshold
//
this.numMemoryThreshold.Increment = new decimal(new int[] {
50,
0,
0,
0});
this.numMemoryThreshold.Location = new System.Drawing.Point(202, 82);
this.numMemoryThreshold.Maximum = new decimal(new int[] {
3000,
0,
0,
0});
this.numMemoryThreshold.Minimum = new decimal(new int[] {
200,
0,
0,
0});
this.numMemoryThreshold.Name = "numMemoryThreshold";
this.numMemoryThreshold.Size = new System.Drawing.Size(97, 20);
this.numMemoryThreshold.TabIndex = 3;
this.numMemoryThreshold.TextSuffix = " MB";
this.toolTip.SetToolTip(this.numMemoryThreshold, "Minimum amount of memory usage by the browser process to trigger the cleanup.\r\nTh" +
"is is not a limit, the usage is allowed to exceed this value.");
this.numMemoryThreshold.Value = new decimal(new int[] {
350,
0,
0,
0});
//
// labelMemoryUsage // labelMemoryUsage
// //
this.labelMemoryUsage.AutoSize = true; this.labelMemoryUsage.AutoSize = true;
@ -273,10 +271,10 @@ private void InitializeComponent() {
this.Controls.Add(this.labelApp); this.Controls.Add(this.labelApp);
this.Name = "TabSettingsAdvanced"; this.Name = "TabSettingsAdvanced";
this.Size = new System.Drawing.Size(340, 328); this.Size = new System.Drawing.Size(340, 328);
((System.ComponentModel.ISupportInitialize)(this.numMemoryThreshold)).EndInit();
this.panelApp.ResumeLayout(false); this.panelApp.ResumeLayout(false);
this.panelPerformance.ResumeLayout(false); this.panelPerformance.ResumeLayout(false);
this.panelPerformance.PerformLayout(); this.panelPerformance.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.numMemoryThreshold)).EndInit();
this.panelConfiguration.ResumeLayout(false); this.panelConfiguration.ResumeLayout(false);
this.ResumeLayout(false); this.ResumeLayout(false);
this.PerformLayout(); this.PerformLayout();

View File

@ -0,0 +1,91 @@
using System;
using System.Diagnostics;
using System.Timers;
using System.Windows.Forms;
using CefSharp;
using Timer = System.Timers.Timer;
namespace TweetDuck.Core.Utils{
sealed class MemoryUsageTracker : IDisposable{
private const int IntervalMemoryCheck = 60000*30; // 30 minutes
private const int IntervalCleanupAttempt = 60000*5; // 5 minutes
private readonly string script;
private readonly Timer timer;
private Form owner;
private IBrowser browser;
private long threshold;
private bool needsCleanup;
public MemoryUsageTracker(string cleanupFunctionName){
this.script = $"window.{cleanupFunctionName} && window.{cleanupFunctionName}()";
this.timer = new Timer{ Interval = IntervalMemoryCheck };
this.timer.Elapsed += timer_Elapsed;
}
public void Start(Form owner, IBrowser browser, int thresholdMB){
Stop();
this.owner = owner;
this.browser = browser;
this.threshold = thresholdMB*1024L*1024L;
this.timer.SynchronizingObject = owner;
this.timer.Start();
}
public void Stop(){
timer.Stop();
timer.SynchronizingObject = null;
owner = null;
browser = null;
SetNeedsCleanup(false);
}
public void Dispose(){
timer.SynchronizingObject = null;
timer.Dispose();
owner = null;
browser = null;
}
private void SetNeedsCleanup(bool value){
if (needsCleanup != value){
needsCleanup = value;
timer.Interval = value ? IntervalCleanupAttempt : IntervalMemoryCheck; // restarts timer
}
}
private void timer_Elapsed(object sender, ElapsedEventArgs e){
if (owner == null || browser == null){
return;
}
if (needsCleanup){
if (!owner.ContainsFocus){
using(IFrame frame = browser.MainFrame){
frame.EvaluateScriptAsync(script).ContinueWith(task => {
JavascriptResponse response = task.Result;
if (response.Success && (response.Result as bool? ?? false)){
SetNeedsCleanup(false);
}
});
}
}
}
else{
try{
using(Process process = BrowserProcesses.FindProcess(browser)){
if (process?.PrivateMemorySize64 > threshold){
SetNeedsCleanup(true);
}
}
}catch{
// ignore I guess?
}
}
}
}
}

View File

@ -784,6 +784,40 @@
}; };
} }
//
// Block: Memory cleanup check and execution.
//
window.TDGF_tryRunCleanup = function(){
// all textareas are empty
if ($("textarea").is(function(){
return $(this).val().length > 0;
})){
return false;
}
// no modals are visible
if ($("#open-modal").is(":visible") || !$(".js-modals-container").is(":empty")){
return false;
}
// all columns are in a default state
if ($("section.js-column").is(".is-shifted-1,.is-shifted-2")){
return false;
}
// all columns are scrolled to top
if ($(".js-column-scroller").is(function(){
return $(this).scrollTop() > 0;
})){
return false;
}
// cleanup
window.gc && window.gc();
window.location.reload();
return true;
};
// //
// Block: Disable TweetDeck metrics. // Block: Disable TweetDeck metrics.
// //

View File

@ -203,6 +203,7 @@
</Compile> </Compile>
<Compile Include="Core\Notification\Screenshot\TweetScreenshotManager.cs" /> <Compile Include="Core\Notification\Screenshot\TweetScreenshotManager.cs" />
<Compile Include="Core\Utils\InjectedHTML.cs" /> <Compile Include="Core\Utils\InjectedHTML.cs" />
<Compile Include="Core\Utils\MemoryUsageTracker.cs" />
<Compile Include="Core\Utils\TwoKeyDictionary.cs" /> <Compile Include="Core\Utils\TwoKeyDictionary.cs" />
<Compile Include="Core\Utils\WindowState.cs" /> <Compile Include="Core\Utils\WindowState.cs" />
<Compile Include="Core\Utils\WindowsUtils.cs" /> <Compile Include="Core\Utils\WindowsUtils.cs" />