More teaking memory alerting

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/ec/trunk@38788 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2015-07-13 10:02:31 +00:00
parent 0b4401c2d9
commit 783d4cfb6c
3 changed files with 61 additions and 23 deletions

View file

@ -1,3 +1,10 @@
2015-07-13 Richard Frith-Macdonald <rfm@gnu.org>
* EcProcess.h:
* EcProcess.m:
Restore lost effect of -ecNotLeaked to moderate changes in our idea
of when we should generate a warening about potential leaks
2015-07-08 Richard Frith-Macdonald <rfm@gnu.org> 2015-07-08 Richard Frith-Macdonald <rfm@gnu.org>
* EcProcess.h: * EcProcess.h:

View file

@ -278,7 +278,8 @@ extern NSString* cmdVersion(NSString *ver);
* This may be used to specify the total process memory usage * This may be used to specify the total process memory usage
* (in megabytes) before memory usage alerting may begin.<br /> * (in megabytes) before memory usage alerting may begin.<br />
* Memory usage 'error' reports are then generated every time * Memory usage 'error' reports are then generated every time
* the average (over ten minutes) memory usage exceeds a warning * the average (over ten minutes) memory usage (adjusted by the
* average memory known not leaked) exceeds a warning
* threshold (the threshold is then increased).<br /> * threshold (the threshold is then increased).<br />
* If this setting is not specified (or a negative or excessive value * If this setting is not specified (or a negative or excessive value
* is specified) then memory is monitored for ten minutes and * is specified) then memory is monitored for ten minutes and
@ -293,7 +294,8 @@ extern NSString* cmdVersion(NSString *ver);
* <term>EcMemoryIncrement</term> * <term>EcMemoryIncrement</term>
* <desc> * <desc>
* This integer value controls the (KBytes) increment (from * This integer value controls the (KBytes) increment (from
* current peak value) in process memory usage after which * current peak value) in process memory usage (adjusted by the
* average memory known not leaked) after which
* an alert is generated.<br /> * an alert is generated.<br />
* If this is not set (or is set to a value less than 10KB or * If this is not set (or is set to a value less than 10KB or
* greater than 1GB) then a value of 5MB is used.<br /> * greater than 1GB) then a value of 5MB is used.<br />
@ -321,7 +323,8 @@ extern NSString* cmdVersion(NSString *ver);
* <term>EcMemoryPercentage</term> * <term>EcMemoryPercentage</term>
* <desc> * <desc>
* This integer value controls the increase in the alerting * This integer value controls the increase in the alerting
* threshold after which a memory usage alert is generated.<br /> * threshold (adjusted by the average memory known not leaked)
* after which a memory usage alert is generated.<br />
* The increase is calculated as a percentage of the current * The increase is calculated as a percentage of the current
* peak memory usage value when an alert is generated.<br /> * peak memory usage value when an alert is generated.<br />
* If this is not set (or is set to a value less than 1 or * If this is not set (or is set to a value less than 1 or
@ -970,8 +973,10 @@ extern NSString* cmdVersion(NSString *ver);
- (void) ecNewMinute: (NSCalendarDate*)when; - (void) ecNewMinute: (NSCalendarDate*)when;
/** Return heap memory known not to be leaked ... for use in internal /** Return heap memory known not to be leaked ... for use in internal
* monitoring of memory usage. You should override this ti add in any * monitoring of memory usage. You should override this to add in any
* heap store you have used and know is not leaked. * heap store you have used and know is not leaked.<br />
* When generating error messages alerting about possible memory leaks,
* this value is taken into consideration.
*/ */
- (NSUInteger) ecNotLeaked; - (NSUInteger) ecNotLeaked;

View file

@ -520,13 +520,19 @@ ecHostName()
static uint64_t memMaximum = 0; static uint64_t memMaximum = 0;
static uint64_t memAllowed = 0; static uint64_t memAllowed = 0;
static uint64_t excAvge = 0; // current period average
static uint64_t memAvge = 0; // current period average static uint64_t memAvge = 0; // current period average
static uint64_t memStrt = 0; // usage at first check static uint64_t excStrt = 0; // excluded usage at first check
static uint64_t memLast = 0; // usage at last check static uint64_t memStrt = 0; // total usage at first check
static uint64_t memPrev = 0; // usage at previous warning static uint64_t excLast = 0; // excluded usage at last check
static uint64_t memPeak = 0; // peak usage static uint64_t memLast = 0; // total usage at last check
static uint64_t memWarn = 0; // next warning point static uint64_t excPrev = 0; // excluded usage at previous warning
static uint64_t memPrev = 0; // total usage at previous warning
static uint64_t excPeak = 0; // excluded peak usage
static uint64_t memPeak = 0; // total peak usage
static uint64_t memWarn = 0; // next warning interval
static uint64_t memSlot = 0; // minute counter static uint64_t memSlot = 0; // minute counter
static uint64_t excRoll[10]; // last N values
static uint64_t memRoll[10]; // last N values static uint64_t memRoll[10]; // last N values
#define MEMCOUNT (sizeof(memRoll)/sizeof(*memRoll)) #define MEMCOUNT (sizeof(memRoll)/sizeof(*memRoll))
static NSDate *memTime = nil; // Time of last alert static NSDate *memTime = nil; // Time of last alert
@ -3395,7 +3401,7 @@ With two parameters ('maximum' and a number),\n\
@" %"PRIu64"KB (start)\n", @" %"PRIu64"KB (start)\n",
memAvge/1024, memStrt/1024]; memAvge/1024, memStrt/1024];
[self cmdPrintf: @" %"PRIu64"KB (reserved)\n", [self cmdPrintf: @" %"PRIu64"KB (reserved)\n",
((uint64_t)[self ecNotLeaked])/1024]; excLast/1024];
if (memSlot < MEMCOUNT) if (memSlot < MEMCOUNT)
{ {
[self cmdPrintf: @"Memory error reporting disabled (for %d min" [self cmdPrintf: @"Memory error reporting disabled (for %d min"
@ -4312,6 +4318,7 @@ With two parameters ('maximum' and a number),\n\
} }
fclose(fptr); fclose(fptr);
} }
excLast = (uint64_t)[self ecNotLeaked];
/* Do initial population so we can work immediately. /* Do initial population so we can work immediately.
*/ */
@ -4319,21 +4326,27 @@ With two parameters ('maximum' and a number),\n\
{ {
for (i = 1; i < MEMCOUNT; i++) for (i = 1; i < MEMCOUNT; i++)
{ {
excRoll[i] = excLast;
memRoll[i] = memLast; memRoll[i] = memLast;
} }
memPrev = memStrt = memLast; memPrev = memStrt = memLast;
excPrev = excStrt = excLast;
} }
excRoll[memSlot % MEMCOUNT] = excLast;
memRoll[memSlot % MEMCOUNT] = memLast; memRoll[memSlot % MEMCOUNT] = memLast;
memSlot++; memSlot++;
/* Find the average usage over the last set of samples. /* Find the average usage over the last set of samples.
* Round up to a block size. * Round up to a block size.
*/ */
excAvge = 0;
memAvge = 0; memAvge = 0;
for (i = 0; i < MEMCOUNT; i++) for (i = 0; i < MEMCOUNT; i++)
{ {
excAvge += excRoll[i];
memAvge += memRoll[i]; memAvge += memRoll[i];
} }
excAvge /= MEMCOUNT;
memAvge /= MEMCOUNT; memAvge /= MEMCOUNT;
/* Convert to 1KB blocks. /* Convert to 1KB blocks.
@ -4342,6 +4355,10 @@ With two parameters ('maximum' and a number),\n\
{ {
memAvge = ((memAvge / 1024) + 1) * 1024; memAvge = ((memAvge / 1024) + 1) * 1024;
} }
if (excAvge % 1024)
{
excAvge = ((excAvge / 1024) + 1) * 1024;
}
/* Update peak memory usage if necessary. /* Update peak memory usage if necessary.
*/ */
@ -4349,6 +4366,10 @@ With two parameters ('maximum' and a number),\n\
{ {
memPeak = memLast; memPeak = memLast;
} }
if (excLast > excPeak)
{
excPeak = excLast;
}
/* If we have a defined maximum memory usage for the process, /* If we have a defined maximum memory usage for the process,
* we should shut down with a non-zero status to get a restart. * we should shut down with a non-zero status to get a restart.
@ -4363,12 +4384,12 @@ With two parameters ('maximum' and a number),\n\
return; return;
} }
/* If the average memory usage is above the threshold, we alert and reset /* If the average memory usage is above the threshold (adjusted by any
* the threshold. * change in known unleaked memory), we alert and reset the threshold.
* During the first ten minutes though, we always adjust the threshold and * During the first ten minutes though, we always adjust the threshold and
* we suppress any warnings. This gives us a more stable starting point. * we suppress any warnings. This gives us a more stable starting point.
*/ */
if (memAvge > memWarn || memSlot < MEMCOUNT) if (memAvge + excPrev - excAvge > memWarn || memSlot < MEMCOUNT)
{ {
NSInteger inc; NSInteger inc;
NSInteger pct; NSInteger pct;
@ -4420,24 +4441,29 @@ With two parameters ('maximum' and a number),\n\
*/ */
if (memSlot >= MEMCOUNT) if (memSlot >= MEMCOUNT)
{ {
uint64_t prev; uint64_t ePrev;
uint64_t mPrev;
NSDate *when; NSDate *when;
prev = memPrev; ePrev = excPrev;
mPrev = memPrev;
when = AUTORELEASE(memTime); when = AUTORELEASE(memTime);
excPrev = excAvge;
memPrev = memAvge; memPrev = memAvge;
memTime = [NSDate new]; memTime = [NSDate new];
if (nil == when) if (nil == when)
{ {
[self cmdError: @"Average memory usage grown from %" [self cmdError: @"Average memory usage grown by %ldKB"
PRIu64"KB to %"PRIu64"KB (reserved: %"PRIu64"KB)", @" with %ldKB accounted for; possible leak of %ldKB",
prev/1024, memAvge/1024, ((uint64_t)[self ecNotLeaked])/1024]; (long)(memAvge - mPrev)/1024, (long)(excAvge - ePrev)/1024,
(long)(memAvge - mPrev + ePrev - excAvge)/1024];
} }
else else
{ {
[self cmdError: @"Average memory usage grown from %" [self cmdError: @"Average memory usage grown by %ldKB"
PRIu64"KB to %"PRIu64"KB (reserved: %"PRIu64"KB) since %@", @" with %ldKB accounted for; possible leak of %ldKB since %@",
prev/1024, memAvge/1024, ((uint64_t)[self ecNotLeaked])/1024, (long)(memAvge - mPrev)/1024, (long)(excAvge - ePrev)/1024,
(long)(memAvge - mPrev + ePrev - excAvge)/1024,
when]; when];
} }
} }
@ -4447,7 +4473,7 @@ With two parameters ('maximum' and a number),\n\
{ {
[self cmdDbg: cmdDetailDbg [self cmdDbg: cmdDetailDbg
msg: @"Memory usage %"PRIu64"KB (reserved: %"PRIu64"KB)", msg: @"Memory usage %"PRIu64"KB (reserved: %"PRIu64"KB)",
memLast/1024, ((uint64_t)[self ecNotLeaked])/1024]; memLast/1024, excLast/1024];
} }
} }