mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-01-28 07:14:40 +08:00
fix: memory leak when switching profiles
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
- 修复无网络时无限请求 IP 归属查询
|
||||
- 修复 WebDAV 页面重试逻辑
|
||||
- 修复 Linux 通过 GUI 安装服务模式权限不符合预期
|
||||
- 修复切换订阅所导致的内存持续增长
|
||||
|
||||
<details>
|
||||
<summary><strong> ✨ 新增功能 </strong></summary>
|
||||
|
||||
@@ -189,6 +189,10 @@ impl Config {
|
||||
pub async fn generate() -> Result<()> {
|
||||
let (config, exists_keys, logs) = enhance::enhance().await;
|
||||
|
||||
Self::runtime().await.edit_draft(|d| {
|
||||
d.clean_all();
|
||||
});
|
||||
|
||||
Self::runtime().await.edit_draft(|d| {
|
||||
*d = IRuntime {
|
||||
config: Some(config),
|
||||
|
||||
@@ -22,6 +22,13 @@ impl IRuntime {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn clean_all(&mut self) {
|
||||
self.config = None;
|
||||
self.exists_keys.clear();
|
||||
self.chain_logs.clear();
|
||||
}
|
||||
|
||||
// 这里只更改 allow-lan | ipv6 | log-level | tun
|
||||
#[inline]
|
||||
pub fn patch_config(&mut self, patch: &Mapping) {
|
||||
|
||||
@@ -13,6 +13,7 @@ use self::{
|
||||
seq::{SeqMap, use_seq},
|
||||
tun::use_tun,
|
||||
};
|
||||
use crate::process::AsyncHandler;
|
||||
use crate::utils::dirs;
|
||||
use crate::{config::Config, utils::tmpl};
|
||||
use crate::{config::IVerge, constants};
|
||||
@@ -33,6 +34,7 @@ struct ConfigValues {
|
||||
socks_enabled: bool,
|
||||
http_enabled: bool,
|
||||
enable_dns_settings: bool,
|
||||
enable_external_controller: bool,
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
redir_enabled: bool,
|
||||
#[cfg(target_os = "linux")]
|
||||
@@ -108,13 +110,22 @@ async fn get_config_values() -> ConfigValues {
|
||||
..
|
||||
} = *verge_arc;
|
||||
|
||||
let (clash_core, enable_tun, enable_builtin, socks_enabled, http_enabled, enable_dns_settings) = (
|
||||
let (
|
||||
clash_core,
|
||||
enable_tun,
|
||||
enable_builtin,
|
||||
socks_enabled,
|
||||
http_enabled,
|
||||
enable_dns_settings,
|
||||
enable_external_controller,
|
||||
) = (
|
||||
Some(verge_arc.get_valid_clash_core()),
|
||||
enable_tun_mode.unwrap_or(false),
|
||||
enable_builtin_enhanced.unwrap_or(true),
|
||||
verge_socks_enabled.unwrap_or(false),
|
||||
verge_http_enabled.unwrap_or(false),
|
||||
enable_dns_settings.unwrap_or(false),
|
||||
verge_arc.enable_external_controller.unwrap_or(false),
|
||||
);
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
@@ -134,6 +145,7 @@ async fn get_config_values() -> ConfigValues {
|
||||
socks_enabled,
|
||||
http_enabled,
|
||||
enable_dns_settings,
|
||||
enable_external_controller,
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
redir_enabled,
|
||||
#[cfg(target_os = "linux")]
|
||||
@@ -378,11 +390,12 @@ fn process_profile_items(
|
||||
(config, exists_keys, result_map)
|
||||
}
|
||||
|
||||
async fn merge_default_config(
|
||||
fn merge_default_config(
|
||||
mut config: Mapping,
|
||||
clash_config: Mapping,
|
||||
socks_enabled: bool,
|
||||
http_enabled: bool,
|
||||
enable_external_controller: bool,
|
||||
#[cfg(not(target_os = "windows"))] redir_enabled: bool,
|
||||
#[cfg(target_os = "linux")] tproxy_enabled: bool,
|
||||
) -> Mapping {
|
||||
@@ -433,19 +446,8 @@ async fn merge_default_config(
|
||||
}
|
||||
}
|
||||
// 处理 external-controller 键的开关逻辑
|
||||
if key.as_str() == Some("external-controller") {
|
||||
let enable_external_controller = Config::verge()
|
||||
.await
|
||||
.latest_arc()
|
||||
.enable_external_controller
|
||||
.unwrap_or(false);
|
||||
|
||||
if enable_external_controller {
|
||||
config.insert(key, value);
|
||||
} else {
|
||||
// 如果禁用了外部控制器,设置为空字符串
|
||||
config.insert(key, "".into());
|
||||
}
|
||||
if key.as_str() == Some("external-controller") && !enable_external_controller {
|
||||
config.insert(key, "".into());
|
||||
} else {
|
||||
config.insert(key, value);
|
||||
}
|
||||
@@ -602,6 +604,7 @@ pub async fn enhance() -> (Mapping, HashSet<String>, HashMap<String, ResultLog>)
|
||||
socks_enabled,
|
||||
http_enabled,
|
||||
enable_dns_settings,
|
||||
enable_external_controller,
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
redir_enabled,
|
||||
#[cfg(target_os = "linux")]
|
||||
@@ -620,48 +623,58 @@ pub async fn enhance() -> (Mapping, HashSet<String>, HashMap<String, ResultLog>)
|
||||
let global_script = profile.global_script;
|
||||
let profile_name = profile.profile_name;
|
||||
|
||||
// process globals
|
||||
let (config, exists_keys, result_map) = process_global_items(config, global_merge, global_script, &profile_name);
|
||||
let (config, exists_keys_set, result_map) = AsyncHandler::spawn_blocking(move || {
|
||||
// process globals
|
||||
let (config, exists_keys, result_map) =
|
||||
process_global_items(config, global_merge, global_script, &profile_name);
|
||||
|
||||
// process profile-specific items
|
||||
let (config, exists_keys, result_map) = process_profile_items(
|
||||
config,
|
||||
exists_keys,
|
||||
result_map,
|
||||
rules_item,
|
||||
proxies_item,
|
||||
groups_item,
|
||||
merge_item,
|
||||
script_item,
|
||||
&profile_name,
|
||||
);
|
||||
// process profile-specific items
|
||||
let (config, exists_keys, result_map) = process_profile_items(
|
||||
config,
|
||||
exists_keys,
|
||||
result_map,
|
||||
rules_item,
|
||||
proxies_item,
|
||||
groups_item,
|
||||
merge_item,
|
||||
script_item,
|
||||
&profile_name,
|
||||
);
|
||||
|
||||
// merge default clash config
|
||||
let config = merge_default_config(
|
||||
config,
|
||||
clash_config,
|
||||
socks_enabled,
|
||||
http_enabled,
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
redir_enabled,
|
||||
#[cfg(target_os = "linux")]
|
||||
tproxy_enabled,
|
||||
)
|
||||
.await;
|
||||
// merge default clash config
|
||||
let config = merge_default_config(
|
||||
config,
|
||||
clash_config,
|
||||
socks_enabled,
|
||||
http_enabled,
|
||||
enable_external_controller,
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
redir_enabled,
|
||||
#[cfg(target_os = "linux")]
|
||||
tproxy_enabled,
|
||||
);
|
||||
|
||||
// builtin scripts
|
||||
let mut config = apply_builtin_scripts(config, clash_core, enable_builtin);
|
||||
// builtin scripts
|
||||
let mut config = apply_builtin_scripts(config, clash_core.clone(), enable_builtin);
|
||||
|
||||
config = cleanup_proxy_groups(config);
|
||||
config = cleanup_proxy_groups(config);
|
||||
|
||||
config = use_tun(config, enable_tun);
|
||||
config = use_sort(config);
|
||||
config = use_tun(config, enable_tun);
|
||||
config = use_sort(config);
|
||||
|
||||
let mut exists_keys_set = HashSet::new();
|
||||
exists_keys_set.extend(exists_keys);
|
||||
|
||||
(config, exists_keys_set, result_map)
|
||||
})
|
||||
.await
|
||||
.unwrap_or_else(|e| {
|
||||
logging!(error, Type::Core, "enhance task join error: {}", e);
|
||||
(Mapping::new(), HashSet::new(), HashMap::new())
|
||||
});
|
||||
|
||||
// dns settings
|
||||
config = apply_dns_settings(config, enable_dns_settings).await;
|
||||
|
||||
let mut exists_keys_set = HashSet::new();
|
||||
exists_keys_set.extend(exists_keys);
|
||||
let config = apply_dns_settings(config, enable_dns_settings).await;
|
||||
|
||||
(config, exists_keys_set, result_map)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user