Menu

#21 SegmentsReader memory leak

closed
nobody
None
5
2004-11-26
2004-10-15
Jacquie
No

SegmentsReader was not deleting its NormsCache so I
added the following :

void SegmentsReader::closeNorms() {
LOCK_MUTEX(norms_mutex);
map<const
char_t*,l_byte_t*,lucene::util::charCompare>::iterator
itr = normsCache.begin();
while (itr != normsCache.end
()) {

delete []itr-
>second;

itr ++;
}
UNLOCK_MUTEX(norms_mutex);
}

which I call in
void SegmentsReader::doClose() {
LOCK_MUTEX(doClose_LOCK);
for (int_t i = 0; i < readersLength;
i++){
readers[i]->close();
}
closeNorms();
UNLOCK_MUTEX(doClose_LOCK);
}

I also added

void closeNorms();

to segmentsReader.h as a private method.

It seems to work ok but I may not know entirely what I
am doing

Discussion

  • Ken Ensdorf

    Ken Ensdorf - 2004-10-15

    Logged In: YES
    user_id=671771

    Actually the normsCache, which is an instance of VoidMap,
    takes care of the deletion of its data upon destruction of the
    object. This is specified in the call to the contructor in the
    initializer list of SegmentsReader. Unfortunately the data in
    the map can get corrupted, since it's being loaded with string
    keys that may be deleted while still in use by the map. The
    following code in the getNorms() method:

    normsCache.put(const_cast<char_t*>(field), bytes);

    should be changed to:

    char_t* key = stringDuplicate(field);
    normsCache.put(key, bytes);

    Since we are now allocatiing the storage for the keys, we
    need to tell the map to delete the keys when it is destroyed,
    so, in the constructor's initializer list, change:

    normsCache(false, util::DELETE_TYPE_NONE,
    true, util::DELETE_TYPE_DELETE_ARRAY)

    to:

    normsCache(true, util::DELETE_TYPE_DELETE_ARRAY,
    true, util::DELETE_TYPE_DELETE_ARRAY)

    That should fix the problem.

     
  • David S. Rushby

    David S. Rushby - 2004-11-01

    Logged In: YES
    user_id=414645

    Are you (Jacquie) using version 0.8.12? On 2004.08.13
    (after 0.8.12's release, I guess), I added the following
    code to SegmentsReader's constructor:
    -----------------------------------------------------------
    // 2004.08.13: Fixed Erik-Kay-reported failure to free
    normsCache's *values*.
    normsCache.setDoDelete(false, DELETE_TYPE_DELETE_ARRAY);
    // The memory underlying normsCache's *keys* is managed
    by the Term class
    // (char_t* Term::field), so normsCache mustn't free its
    keys.
    -----------------------------------------------------------

    The "Erik-Kay-report" of which I spoke is here:
    http://sourceforge.net/mailarchive/forum.php?thread_id=5293141&forum_id=33782

    If I recall correctly, I reviewed the CLucene-internal code
    that touches the char_t* field memory in order to verify
    that a scenario such as the one Ken describes does not arise
    within the CLucene itself. As long as the Term that manages
    the char_t* field memory survives at least as long as the
    SegmentsReader, corruption shouldn't occur. Even if my
    memory of that code review and the correctness of its
    conclusions can be trusted, I agree that it would be all too
    easy for a client programmer to provoke such a scenario, so
    unless Ben stops me, I'll implement Ken's suggestion.

     
  • John Wheeler

    John Wheeler - 2004-11-01

    Logged In: YES
    user_id=1149323

    Ken

    You mean:

    normsCache.setDoDelete(false, DELETE_TYPE_DELETE_ARRAY);

    changing into:

    normsCache.setDoDelete(true, DELETE_TYPE_DELETE_ARRAY);

    right? Or are you talking about code that ain't in the
    repository yet?

     
  • Ken Ensdorf

    Ken Ensdorf - 2004-11-01

    Logged In: YES
    user_id=671771

    John-
    I think you are right. I added that line to the initializer list for
    SegmentsReader. I guess you can get the same effect by
    calling setDoDelete(), so either is probably ok.

     
  • John Wheeler

    John Wheeler - 2004-11-03

    Logged In: YES
    user_id=1149323

    Is there a reason this fix is not yet in the CVS repository?

     
  • David S. Rushby

    David S. Rushby - 2004-11-04

    Logged In: YES
    user_id=414645

    The reason is that my brief window of opportunity to work on
    CLucene closed. I might be able to spend some time on it
    this weekend, but I have both commercial clients and another
    two open source projects making urgent demands on my time.

    If you're sufficiently interested (the volume of your bug
    reports suggests that you are), you might ask Ben for
    developer rights to the CLucene SourceForge project so that
    you can make CVS commits yourself. (I apologize to Ben if
    I'm overstepping my bounds in making this suggestion; I am,
    after all, just a contributor to this project, not a founder
    or an administrator.)

     
  • Jacquie

    Jacquie - 2004-11-04

    Logged In: YES
    user_id=1113468

    I am sorry - I was looking at 0.8.11 because for some reason
    I can't get 0.8.12 to link with the example/demo program. I
    was testing things out with 0.8.12 and then seeing if the
    problem showed up in the 0.8.11 demo and then comparing
    the code. In this case I was getting a problem in 0.8.12 that
    seemed to be related to this problem in 0.8.11 and forgot to
    check the code. The actual problem turned out to be
    something else entirely.

    I have however implemented the changes suggested by Ken
    and amended by John and all seems to be well.

     
  • John Wheeler

    John Wheeler - 2004-11-18

    Logged In: YES
    user_id=1149323

    Fixed in CVS

    SegmentsReader.cpp 1.12

    I implemented the fix posted by Ken and amend by me ;) and
    commited the change in CVS.

     
  • John Wheeler

    John Wheeler - 2004-11-18
    • status: open --> closed
     
  • John Wheeler

    John Wheeler - 2004-11-26

    Logged In: YES
    user_id=1149323

    normsCache.setDoDelete(true, DELETE_TYPE_DELETE_ARRAY); was
    not good enough. The normcache did not delete its values,
    which cause a memory leak. The suggestion by Ken, adding
    normsCache(true, util::DELETE_TYPE_DELETE_ARRAY,
    true, util::DELETE_TYPE_DELETE_ARRAY) is the proper solution

     
  • John Wheeler

    John Wheeler - 2004-11-26
    • status: closed --> open
     
  • John Wheeler

    John Wheeler - 2004-11-26

    Logged In: YES
    user_id=1149323

    Fixed in CVS

    SegmentsReader.cpp 1.13

     
  • John Wheeler

    John Wheeler - 2004-11-26
    • status: open --> closed
     

Log in to post a comment.