> I'd like to hear your thoughts about these logs before trying > to get into them and understand what's wrong.
The memory losses are sorted by size, so maybe we can try to fix at least the biggest memory leaks. For instance: ==22649== 47,920 bytes in 960 blocks are indirectly lost in loss record 920 of 921 ==22649== at 0x402471C: operator new(unsigned int) (vg_replace_malloc.c:255) ==22649== by 0x4E75627: std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >::_Rep::_S_create(unsigned int, unsigned int, std::allocator<wchar_t> const&) (in /usr/lib/libstdc++.so.6.0.15) ==22649== by 0x8182DD8: lyx::Paragraph::asString(int, int, int) const (basic_string.h:1543) ==22649== by 0x818C5F7: lyx::Paragraph::collectWords() (Paragraph.cpp:3503) ==22649== by 0x818C919: lyx::Paragraph::updateWords() (Paragraph.cpp:3531) ... Refers to: void Paragraph::collectWords() { // This is the value that needs to be exposed in the preferences // to resolve bug #6760. static int minlength = 6; pos_type n = size(); for (pos_type pos = 0; pos < n; ++pos) { if (isWordSeparator(pos)) continue; pos_type from = pos; locateWord(from, pos, WHOLE_WORD); if (pos - from >= minlength) { docstring word = asString(from, pos, AS_STR_NONE); FontList::const_iterator cit = d->fontlist_.fontIterator(pos); if (cit == d->fontlist_.end()) return; Language const * lang = cit->font().language(); d->words_[*lang].insert(word); // HERE HERE HERE HERE HERE } } } We call insert on words_[*lang], that is: class Paragraph::Private { [...] typedef set<docstring> Words; typedef map<Language, Words> LangWordsMap; /// LangWordsMap words_; [...] }; In the destructor: Paragraph::~Paragraph() { deregisterWords(); delete d; } void Paragraph::deregisterWords() { Private::LangWordsMap::const_iterator itl = d->words_.begin(); Private::LangWordsMap::const_iterator ite = d->words_.end(); for (; itl != ite; ++itl) { WordList * wl = theWordList(itl->first); Private::Words::const_iterator it = (itl->second).begin(); Private::Words::const_iterator et = (itl->second).end(); for (; it != et; ++it) wl->remove(*it); } d->words_.clear(); } But in wl->remove... void WordList::remove(docstring const & w) { Impl::Words::iterator it = d->words_.find(w); if (it != d->words_.end()) { it.data()--; d->words_.change_weight(it, 0); // We will not erase here, but instead we just leave it // in the btree with weight 0. This avoid too much // reorganisation of the tree all the time. //if (it.data() == 0) // d->words_.erase(w); } } If I'm correct we're not removing the words to avoid tree reorganization, but when we call delete d; in the destructor all the data remains orphan: 47,920 bytes are indirectly lost. This is a serious memory leak IMHO, as paragraph are created and destroyed quite frequently. venom00