Add memory_cleanup on tear_down, and add more memory_cleanup.

This commit is contained in:
Andrea Cavalli 2021-01-12 01:37:17 +01:00
parent 5af21e5612
commit a79f835de0
20 changed files with 249 additions and 28 deletions

View File

@ -145,6 +145,9 @@ AnimationsManager::AnimationsManager(Td *td, ActorShared<> parent) : td_(td), pa
}
void AnimationsManager::tear_down() {
// Completely clear memory when closing, to avoid memory leaks
memory_cleanup(true);
parent_.reset();
}
@ -965,13 +968,23 @@ void AnimationsManager::get_current_state(vector<td_api::object_ptr<td_api::Upda
updates.push_back(std::move(update_animation_search_parameters));
}
}
void AnimationsManager::memory_cleanup() {
memory_cleanup(false);
}
void AnimationsManager::memory_cleanup(bool full) {
animations_.clear();
animations_.rehash(0);
saved_animation_ids_.clear();
saved_animation_file_ids_.clear();
}
void AnimationsManager::memory_stats(vector<string> &output) {
output.push_back("\"animations_\":"); output.push_back(std::to_string(animations_.size()));
output.push_back(",");
output.push_back("\"saved_animation_ids_\":"); output.push_back(std::to_string(this->saved_animation_ids_.size()));
output.push_back(",");
output.push_back("\"saved_animation_file_ids_\":"); output.push_back(std::to_string(this->saved_animation_file_ids_.size()));
}

View File

@ -118,6 +118,8 @@ class AnimationsManager : public Actor {
bool is_changed = true;
};
void memory_cleanup(bool full);
const Animation *get_animation(FileId file_id) const;
FileId on_get_animation(unique_ptr<Animation> new_animation, bool replace);

View File

@ -1121,4 +1121,36 @@ void BackgroundManager::get_current_state(vector<td_api::object_ptr<td_api::Upda
updates.push_back(get_update_selected_background_object(true));
}
void BackgroundManager::memory_cleanup() {
memory_cleanup(false);
}
void BackgroundManager::memory_cleanup(bool full) {
backgrounds_.clear();
backgrounds_.rehash(0);
background_id_to_file_source_id_.clear();
background_id_to_file_source_id_.rehash(0);
name_to_background_id_.clear();
name_to_background_id_.rehash(0);
file_id_to_background_id_.clear();
file_id_to_background_id_.rehash(0);
loaded_from_database_backgrounds_.clear();
loaded_from_database_backgrounds_.rehash(0);
installed_background_ids_.clear();
}
void BackgroundManager::memory_stats(vector<string> &output) {
output.push_back("\"backgrounds_\":"); output.push_back(std::to_string(backgrounds_.size()));
output.push_back(",");
output.push_back("\"background_id_to_file_source_id_\":"); output.push_back(std::to_string(background_id_to_file_source_id_.size()));
output.push_back(",");
output.push_back("\"name_to_background_id_\":"); output.push_back(std::to_string(name_to_background_id_.size()));
output.push_back(",");
output.push_back("\"file_id_to_background_id_\":"); output.push_back(std::to_string(file_id_to_background_id_.size()));
output.push_back(",");
output.push_back("\"loaded_from_database_backgrounds_\":"); output.push_back(std::to_string(loaded_from_database_backgrounds_.size()));
output.push_back(",");
output.push_back("\"installed_background_ids_\":"); output.push_back(std::to_string(installed_background_ids_.size()));
}
} // namespace td

View File

@ -33,6 +33,10 @@ class BackgroundManager : public Actor {
public:
BackgroundManager(Td *td, ActorShared<> parent);
void memory_cleanup();
void memory_stats(vector<string> &output);
void get_backgrounds(Promise<Unit> &&promise);
Result<string> get_background_url(const string &name,
@ -92,6 +96,8 @@ class BackgroundManager : public Actor {
void tear_down() override;
void memory_cleanup(bool full);
static string get_background_database_key(bool for_dark_theme);
void save_background_id(bool for_dark_theme) const;

View File

@ -2952,6 +2952,8 @@ ContactsManager::ContactsManager(Td *td, ActorShared<> parent) : td_(td), parent
}
void ContactsManager::tear_down() {
// Completely clear memory when closing, to avoid memory leaks
memory_cleanup(true);
parent_.reset();
}
@ -14681,6 +14683,10 @@ void ContactsManager::get_current_state(vector<td_api::object_ptr<td_api::Update
}
void ContactsManager::memory_cleanup() {
memory_cleanup(false);
}
void ContactsManager::memory_cleanup(bool full) {
auto time = std::time(nullptr);
auto user_ttl = !G()->shared_config().get_option_integer("delete_user_reference_after_seconds", 3600);
@ -14688,7 +14694,9 @@ void ContactsManager::memory_cleanup() {
auto chat_access_hash_cleanup = !G()->shared_config().get_option_boolean("experiment_enable_chat_access_hash_cleanup", true);
/* DESTROY INVALID USERS */
{
if (full) {
users_.clear();
} else {
auto it = users_.begin();
while (it != users_.end()) {
//auto &user = it->second;
@ -14720,9 +14728,11 @@ void ContactsManager::memory_cleanup() {
my_photo_file_id_.clear();
my_photo_file_id_.rehash(0);
if (chat_access_hash_cleanup) {
if (full || chat_access_hash_cleanup) {
/* DESTROY INVALID CHATS */
{
if (full) {
chats_.clear();
} else {
auto it = chats_.begin();
while (it != chats_.end()) {
//auto &chat = it->second;
@ -14738,21 +14748,22 @@ void ContactsManager::memory_cleanup() {
}
}
}
chats_.rehash(0);
}
chats_full_.clear();
chats_full_.rehash(0);
unknown_chats_.clear();
unknown_chats_.rehash(0);
if (chat_access_hash_cleanup) {
if (full || chat_access_hash_cleanup) {
chat_full_file_source_ids_.clear();
chat_full_file_source_ids_.rehash(0);
min_channels_.clear();
min_channels_.rehash(0);
/* DESTROY INVALID CHANNELS */
{
if (full) {
channels_.clear();
} else {
auto it = channels_.begin();
while (it != channels_.end()) {
//auto &channel = it->second;
@ -14775,16 +14786,18 @@ void ContactsManager::memory_cleanup() {
}
unknown_channels_.clear();
unknown_channels_.rehash(0);
if (chat_access_hash_cleanup) {
if (full || chat_access_hash_cleanup) {
channel_full_file_source_ids_.clear();
channel_full_file_source_ids_.rehash(0);
}
//secret_chats_.clear();
//secret_chats_.rehash(0);
//unknown_secret_chats_.clear();
//unknown_secret_chats_.rehash(0);
//secret_chats_with_user_.clear();
//secret_chats_with_user_.rehash(0);
if (full) {
secret_chats_.clear();
secret_chats_.rehash(0);
unknown_secret_chats_.clear();
unknown_secret_chats_.rehash(0);
secret_chats_with_user_.clear();
secret_chats_with_user_.rehash(0);
}
dialog_invite_links_.clear();
dialog_invite_links_.rehash(0);
invite_link_infos_.clear();
@ -14811,10 +14824,12 @@ void ContactsManager::memory_cleanup() {
loaded_from_database_channels_.rehash(0);
unavailable_channel_fulls_.clear();
unavailable_channel_fulls_.rehash(0);
//load_secret_chat_from_database_queries_.clear();
//load_secret_chat_from_database_queries_.rehash(0);
//loaded_from_database_secret_chats_.clear();
//loaded_from_database_secret_chats_.rehash(0);
if (full) {
load_secret_chat_from_database_queries_.clear();
load_secret_chat_from_database_queries_.rehash(0);
loaded_from_database_secret_chats_.clear();
loaded_from_database_secret_chats_.rehash(0);
}
dialog_administrators_.clear();
dialog_administrators_.rehash(0);
uploaded_profile_photos_.clear();

View File

@ -1067,6 +1067,8 @@ class ContactsManager : public Actor {
static const CSlice INVITE_LINK_URLS[3];
void memory_cleanup(bool full);
static bool have_input_peer_user(const User *u, AccessRights access_rights);
static bool have_input_peer_chat(const Chat *c, AccessRights access_rights);
bool have_input_peer_channel(const Channel *c, ChannelId channel_id, AccessRights access_rights,

View File

@ -466,10 +466,16 @@ GroupCallManager::GroupCallManager(Td *td, ActorShared<> parent) : td_(td), pare
GroupCallManager::~GroupCallManager() = default;
void GroupCallManager::tear_down() {
// Completely clear memory when closing, to avoid memory leaks
memory_cleanup(true);
parent_.reset();
}
void GroupCallManager::memory_cleanup() {
memory_cleanup(false);
}
void GroupCallManager::memory_cleanup(bool full) {
this->group_call_participants_.clear();
this->group_call_participants_.rehash(0);
this->group_call_recent_speakers_.clear();

View File

@ -97,6 +97,8 @@ class GroupCallManager : public Actor {
void tear_down() override;
void memory_cleanup(bool full);
static void on_check_group_call_is_joined_timeout_callback(void *group_call_manager_ptr, int64 group_call_id_int);
void on_check_group_call_is_joined_timeout(GroupCallId group_call_id);

View File

@ -165,6 +165,8 @@ InlineQueriesManager::InlineQueriesManager(Td *td, ActorShared<> parent) : td_(t
}
void InlineQueriesManager::tear_down() {
// Completely clear memory when closing, to avoid memory leaks
memory_cleanup(true);
parent_.reset();
}
@ -1846,4 +1848,28 @@ void InlineQueriesManager::remove_recent_inline_bot(UserId bot_user_id, Promise<
promise.set_value(Unit());
}
void InlineQueriesManager::memory_cleanup() {
memory_cleanup(false);
}
void InlineQueriesManager::memory_cleanup(bool full) {
recently_used_bot_user_ids_.clear();
inline_query_results_.clear();
inline_query_results_.rehash(0);
inline_message_contents_.clear();
inline_message_contents_.rehash(0);
query_id_to_bot_user_id_.clear();
query_id_to_bot_user_id_.rehash(0);
}
void InlineQueriesManager::memory_stats(vector<string> &output) {
output.push_back("\"recently_used_bot_user_ids_\":"); output.push_back(std::to_string(recently_used_bot_user_ids_.size()));
output.push_back(",");
output.push_back("\"inline_query_results_\":"); output.push_back(std::to_string(inline_query_results_.size()));
output.push_back(",");
output.push_back("\"inline_message_contents_\":"); output.push_back(std::to_string(inline_message_contents_.size()));
output.push_back(",");
output.push_back("\"query_id_to_bot_user_id_\":"); output.push_back(std::to_string(query_id_to_bot_user_id_.size()));
}
} // namespace td

View File

@ -39,6 +39,10 @@ class InlineQueriesManager : public Actor {
public:
InlineQueriesManager(Td *td, ActorShared<> parent);
void memory_cleanup();
void memory_stats(vector<string> &output);
void after_get_difference();
void answer_inline_query(int64 inline_query_id, bool is_personal,
@ -112,6 +116,8 @@ class InlineQueriesManager : public Actor {
void tear_down() override;
void memory_cleanup(bool full);
int32 recently_used_bots_loaded_ = 0; // 0 - not loaded, 1 - load request was sent, 2 - loaded
MultiPromiseActor resolve_recent_inline_bots_multipromise_{"ResolveRecentInlineBotsMultiPromiseActor"};

View File

@ -28,6 +28,9 @@
#include "td/telegram/AudiosManager.h"
#include "td/telegram/AnimationsManager.h"
#include "td/telegram/GroupCallManager.h"
#include "td/telegram/BackgroundManager.h"
#include "td/telegram/PollManager.h"
#include "td/telegram/InlineQueriesManager.h"
#include "td/telegram/files/FileType.h"
#include "td/telegram/Global.h"
#include "td/telegram/LanguagePackManager.h"
@ -163,6 +166,25 @@ void MemoryManager::get_memory_stats(bool full, Promise<MemoryStats> promise) co
td_->group_call_manager_->memory_stats(output);
output.push_back("}");
output.push_back(",");
output.push_back("\"background_manager_\":{");
td_->background_manager_->memory_stats(output);
output.push_back("}");
output.push_back(",");
output.push_back("\"inline_queries_manager_\":{");
td_->inline_queries_manager_->memory_stats(output);
output.push_back("}");
output.push_back(",");
output.push_back("\"poll_manager_\":{");
td_->poll_manager_->memory_stats(output);
output.push_back("}");
output.push_back("}}");
string s;
@ -190,6 +212,9 @@ void MemoryManager::clean_memory(bool full, Promise<Unit> promise) const {
td_->file_manager_->memory_cleanup();
td_->file_reference_manager_->memory_cleanup();
td_->group_call_manager_->memory_cleanup();
td_->background_manager_->memory_cleanup();
td_->inline_queries_manager_->memory_cleanup();
td_->poll_manager_->memory_cleanup();
#ifdef __linux__
#if defined(__GLIBC__) && !defined(__UCLIBC__) && !defined(__MUSL__)

View File

@ -5924,6 +5924,10 @@ vector<int32> MessagesManager::get_scheduled_server_message_ids(const vector<Mes
}
void MessagesManager::memory_cleanup() {
memory_cleanup(false);
}
void MessagesManager::memory_cleanup(bool full) {
/* CLEAR DELETED MESSAGES CACHE */
{
auto it = dialogs_.begin();
@ -5945,6 +5949,9 @@ void MessagesManager::memory_cleanup() {
found_on_server_dialogs_.rehash(0);
full_message_id_to_file_source_id_.clear();
full_message_id_to_file_source_id_.rehash(0);
if (full) {
dialogs_.clear();
}
}
void MessagesManager::memory_stats(vector<string> &output) {
@ -11987,6 +11994,8 @@ class MessagesManager::DialogFiltersLogEvent {
};
void MessagesManager::tear_down() {
// Completely clear memory when closing, to avoid memory leaks
memory_cleanup(true);
parent_.reset();
}

View File

@ -1734,6 +1734,8 @@ class MessagesManager : public Actor {
static constexpr bool DROP_UPDATES = false;
void memory_cleanup(bool full);
static FullMessageId get_full_message_id(const tl_object_ptr<telegram_api::Message> &message_ptr, bool is_scheduled);
static int32 get_message_date(const tl_object_ptr<telegram_api::Message> &message_ptr);

View File

@ -1689,4 +1689,39 @@ void PollManager::on_binlog_events(vector<BinlogEvent> &&events) {
}
}
void PollManager::memory_cleanup() {
// Completely clear memory when closing, to avoid memory leaks
memory_cleanup(true);
memory_cleanup(false);
}
void PollManager::memory_cleanup(bool full) {
polls_.clear();
polls_.rehash(0);
poll_messages_.clear();
poll_messages_.rehash(0);
pending_answers_.clear();
pending_answers_.rehash(0);
poll_voters_.clear();
poll_voters_.rehash(0);
loaded_from_database_polls_.clear();
loaded_from_database_polls_.rehash(0);
being_closed_polls_.clear();
being_closed_polls_.rehash(0);
}
void PollManager::memory_stats(vector<string> &output) {
output.push_back("\"polls_\":"); output.push_back(std::to_string(polls_.size()));
output.push_back(",");
output.push_back("\"poll_messages_\":"); output.push_back(std::to_string(poll_messages_.size()));
output.push_back(",");
output.push_back("\"pending_answers_\":"); output.push_back(std::to_string(pending_answers_.size()));
output.push_back(",");
output.push_back("\"poll_voters_\":"); output.push_back(std::to_string(poll_voters_.size()));
output.push_back(",");
output.push_back("\"loaded_from_database_polls_\":"); output.push_back(std::to_string(loaded_from_database_polls_.size()));
output.push_back(",");
output.push_back("\"being_closed_polls_\":"); output.push_back(std::to_string(being_closed_polls_.size()));
}
} // namespace td

View File

@ -43,6 +43,10 @@ class PollManager : public Actor {
PollManager &operator=(PollManager &&) = delete;
~PollManager() override;
void memory_cleanup();
void memory_stats(vector<string> &output);
static bool is_local_poll_id(PollId poll_id);
PollId create_poll(string &&question, vector<string> &&options, bool is_anonymous, bool allow_multiple_answers,
@ -141,6 +145,8 @@ class PollManager : public Actor {
void start_up() override;
void tear_down() override;
void memory_cleanup(bool full);
static void on_update_poll_timeout_callback(void *poll_manager_ptr, int64 poll_id_int);
static void on_close_poll_timeout_callback(void *poll_manager_ptr, int64 poll_id_int);

View File

@ -1320,6 +1320,8 @@ void StickersManager::on_load_special_sticker_set(const SpecialStickerSetType &t
}
void StickersManager::tear_down() {
// Completely clear memory when closing, to avoid memory leaks
memory_cleanup();
parent_.reset();
}

View File

@ -405,6 +405,8 @@ WebPagesManager::WebPagesManager(Td *td, ActorShared<> parent) : td_(td), parent
}
void WebPagesManager::tear_down() {
// Completely clear memory when closing, to avoid memory leaks
memory_cleanup();
parent_.reset();
}

View File

@ -3795,6 +3795,10 @@ void FileManager::destroy_query(int32 file_id) {
void FileManager::memory_cleanup() {
memory_cleanup(false);
}
void FileManager::memory_cleanup(bool full) {
LOG(ERROR) << "Initial registered ids: " << file_id_info_.size() << " registered nodes: " << file_nodes_.size();
std::unordered_set<int32> file_to_be_deleted = {};
@ -3802,7 +3806,9 @@ void FileManager::memory_cleanup() {
auto file_ttl = !G()->shared_config().get_option_integer("delete_file_reference_after_seconds", 30);
/* DESTROY OLD file_id_info_ */
if (true) {
if (full) {
file_id_info_.clear();
} else {
auto it = file_id_info_.begin();
auto time = std::time(nullptr);
@ -3868,7 +3874,7 @@ void FileManager::memory_cleanup() {
}
/* DESTROY INVALID FILES */
if (true) {
if (!full) {
auto it = file_id_info_.begin();
while (it != file_id_info_.end()) {
auto is_invalid = false;
@ -3894,7 +3900,9 @@ void FileManager::memory_cleanup() {
}
/* DESTROY INVALID file_nodes_ */
if (true) {
if (full) {
file_nodes_.clear();
} else {
auto it = file_nodes_.begin();
while (it != file_nodes_.end()) {
auto is_invalid = false;
@ -3931,7 +3939,9 @@ void FileManager::memory_cleanup() {
}
/* DESTROY INVALID file_hash_to_file_id_ */
if (true) {
if (full) {
file_hash_to_file_id_.clear();
} else {
auto it = file_hash_to_file_id_.begin();
while (it != file_hash_to_file_id_.end()) {
auto is_invalid = false;
@ -3957,7 +3967,9 @@ void FileManager::memory_cleanup() {
}
/* DESTROY INVALID local_location_to_file_id_ */
if (true) {
if (full) {
local_location_to_file_id_.clear();
} else {
auto it = local_location_to_file_id_.begin();
while (it != local_location_to_file_id_.end()) {
auto is_invalid = false;
@ -3983,7 +3995,9 @@ void FileManager::memory_cleanup() {
}
/* DESTROY INVALID generate_location_to_file_id_ */
if (true) {
if (full) {
generate_location_to_file_id_.clear();
} else {
auto it = generate_location_to_file_id_.begin();
while (it != generate_location_to_file_id_.end()) {
auto is_invalid = false;
@ -4009,7 +4023,9 @@ void FileManager::memory_cleanup() {
}
/* DESTROY INVALID remote_location_info_ */
if (true) {
if (full) {
remote_location_info_.clear();
} else {
remote_location_info_.lock_access_mutex();
std::unordered_map<int32, RemoteInfo> old_remote_info = {};
@ -4049,7 +4065,9 @@ void FileManager::memory_cleanup() {
}
/* DESTROY NULL file_id_info_ */
if (true) {
if (full) {
file_id_info_.clear();
} else {
auto it = file_id_info_.begin();
while (it != file_id_info_.end()) {
auto is_invalid = false;
@ -4072,9 +4090,11 @@ void FileManager::memory_cleanup() {
}
}
file_nodes_.rehash(file_nodes_.size() + 1);
file_hash_to_file_id_.rehash(file_hash_to_file_id_.size() + 1);
file_id_info_.rehash(file_id_info_.size() + 1);
if (!full) {
file_nodes_.rehash(file_nodes_.size() + 1);
file_hash_to_file_id_.rehash(file_hash_to_file_id_.size() + 1);
file_id_info_.rehash(file_id_info_.size() + 1);
}
LOG(ERROR) << "Final registered ids: " << file_id_info_.size() << " registered nodes: " << file_nodes_.size();
}
@ -4091,6 +4111,8 @@ void FileManager::memory_stats(vector<string> &output) {
}
void FileManager::tear_down() {
// Completely clear memory when closing, to avoid memory leaks
memory_cleanup(true);
parent_.reset();
}
} // namespace td

View File

@ -505,6 +505,8 @@ class FileManager : public FileLoadManager::Callback {
private:
void destroy_query(int32 file_id);
void memory_cleanup(bool full);
Result<FileId> check_input_file_id(FileType type, Result<FileId> result, bool is_encrypted, bool allow_zero,
bool is_secure) TD_WARN_UNUSED_RESULT;

View File

@ -24,6 +24,12 @@ class Enumerator {
return map_;
}
void clear() {
map_.clear();
arr_.clear();
next_id = 1;
}
void lock_access_mutex() const {
access_mutex.lock();
}