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:
parent
d77de3bb12
commit
4d77a498f6
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
68
Core/Other/Settings/TabSettingsAdvanced.Designer.cs
generated
68
Core/Other/Settings/TabSettingsAdvanced.Designer.cs
generated
@ -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();
|
||||||
|
91
Core/Utils/MemoryUsageTracker.cs
Normal file
91
Core/Utils/MemoryUsageTracker.cs
Normal 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?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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.
|
||||||
//
|
//
|
||||||
|
@ -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" />
|
||||||
|
Loading…
Reference in New Issue
Block a user