Fixed a large client side memory leak for app_server memory.

* The areas allocated for BBitmaps were never deleted, even though the
  app_server deleted its part when the memory got freed.
* This resulted in a constant memory increase if the application in question
  would operate on many changing large bitmaps, like photos.
* Since the bitmaps are reference counted, we don't actually know when to delete
  the areas, so that the app_server now notifies the client whenever that is
  possible.
* This might fix #6824.
This commit is contained in:
Axel Dörfler 2012-04-29 20:21:40 +02:00
parent 7705d517d1
commit 8e2140fa5e
7 changed files with 42 additions and 7 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2001-2010, Haiku.
* Copyright 2001-2012, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
@ -344,6 +344,12 @@ enum {
AS_LAST_CODE
};
// TODO: move this into a private app header, together with the rest of the
// private message definitions in AppDefs.h
enum {
kMsgDeleteServerMemoryArea = '_DSA',
};
// bitmap allocation flags
enum {
kAllocator = 0x1,

View File

@ -1,5 +1,5 @@
/*
* Copyright 2001-2009, Haiku.
* Copyright 2001-2012, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
@ -601,9 +601,18 @@ BApplication::MessageReceived(BMessage *message)
break;
case kMsgAppServerRestarted:
{
_ReconnectToServer();
break;
case kMsgDeleteServerMemoryArea:
{
int32 serverArea;
if (message->FindInt32("server area", &serverArea) == B_OK) {
// The link is not used, but we currently borrow its lock
BPrivate::AppServerLink link;
fServerAllocator->RemoveArea(serverArea);
}
break;
}
default:

View File

@ -1,5 +1,5 @@
/*
* Copyright 2006-2011, Haiku, Inc. All Rights Reserved.
* Copyright 2006-2012, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
@ -131,6 +131,7 @@ status_t
ServerMemoryAllocator::AreaAndBaseFor(area_id serverArea, area_id& _area,
uint8*& _base)
{
// TODO: why not use a map?
for (int32 i = fAreas.CountItems(); i-- > 0;) {
area_mapping* mapping = (area_mapping*)fAreas.ItemAt(i);

View File

@ -1186,7 +1186,7 @@ BBitmap::_CleanUp()
link.Attach<int32>(fServerToken);
link.Flush();
// TODO: we may want to delete parts of the server memory areas here!
// The server areas are deleted via kMsgDeleteServerMemoryArea message
fArea = -1;
fServerToken = -1;

View File

@ -179,6 +179,8 @@ ClientMemoryAllocator::Free(block* freeBlock)
fChunks.Remove(chunk);
delete_area(chunk->area);
fApplication->NotifyDeleteClientArea(chunk->area);
free(chunk);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2001-2010, Haiku.
* Copyright 2001-2012, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
@ -484,6 +484,21 @@ ServerApp::RemovePicture(ServerPicture* picture)
}
/*! Called from the ClientMemoryAllocator whenever a server area could be
deleted.
A message is then sent to the client telling it that it can delete its
client area, too.
*/
void
ServerApp::NotifyDeleteClientArea(area_id serverArea)
{
BMessage notify(kMsgDeleteServerMemoryArea);
notify.AddInt32("server area", serverArea);
SendMessageToClient(&notify);
}
// #pragma mark - private methods

View File

@ -1,5 +1,5 @@
/*
* Copyright 2001-2010, Haiku.
* Copyright 2001-2012, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
@ -94,6 +94,8 @@ public:
BPrivate::BTokenSpace& ViewTokens() { return fViewTokens; }
void NotifyDeleteClientArea(area_id serverArea);
private:
virtual void _GetLooperName(char* name, size_t size);
virtual void _DispatchMessage(int32 code,