diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h
index 355617a89829743ecae7fbd699b0c7b0602aa8b6..5c68bbbc0bdd597c4b01f861c73465e60ba5cdf7 100644
--- a/indra/llcommon/lltrace.h
+++ b/indra/llcommon/lltrace.h
@@ -283,30 +283,34 @@ class MemStatHandle : public TraceType<MemStatAccumulator>
 
 inline void claim_footprint(MemStatHandle& measurement, S32 size)
 {
+	if(size == 0) return;
 	MemStatAccumulator& accumulator = measurement.getCurrentAccumulator();
 	accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size);
-	accumulator.mAllocated.add(1);
+	accumulator.mFootprintAllocations.record(size);
 }
 
 inline void disclaim_footprint(MemStatHandle& measurement, S32 size)
 {
+	if(size == 0) return;
 	MemStatAccumulator& accumulator = measurement.getCurrentAccumulator();
 	accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size);
-	accumulator.mDeallocated.add(1);
+	accumulator.mFootprintDeallocations.add(size);
 }
 
 inline void claim_shadow(MemStatHandle& measurement, S32 size)
 {
+	if(size == 0) return;
 	MemStatAccumulator& accumulator = measurement.getCurrentAccumulator();
 	accumulator.mShadowSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size);
-	accumulator.mShadowAllocated.add(1);
+	accumulator.mShadowAllocations.record(size);
 }
 
 inline void disclaim_shadow(MemStatHandle& measurement, S32 size)
 {
+	if(size == 0) return;
 	MemStatAccumulator& accumulator = measurement.getCurrentAccumulator();
 	accumulator.mShadowSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size);
-	accumulator.mShadowDeallocated.add(1);
+	accumulator.mShadowDeallocations.add(size);
 }
 
 // measures effective memory footprint of specified type
@@ -465,13 +469,13 @@ class MemTrackable
 
 	void *operator new [](size_t size)
 	{
-		claim_footprint(sMemStat, size);
+		claim_footprint(sMemStat, size, true);
 		return ll_aligned_malloc(ALIGNMENT, size);
 	}
 
 	void operator delete[](void* ptr, size_t size)
 	{
-		disclaim_footprint(sMemStat, size);
+		disclaim_footprint(sMemStat, size, true);
 		ll_aligned_free(ALIGNMENT, ptr);
 	}
 
diff --git a/indra/llcommon/lltraceaccumulators.cpp b/indra/llcommon/lltraceaccumulators.cpp
index 58d0b5b22711bbb04780c419e8799f571cfe80a1..a7bd04415e2b26beae4995ae98bb2d4acc5ad998 100644
--- a/indra/llcommon/lltraceaccumulators.cpp
+++ b/indra/llcommon/lltraceaccumulators.cpp
@@ -239,7 +239,7 @@ void EventAccumulator::addSamples( const EventAccumulator& other, EBufferAppendT
 void EventAccumulator::reset( const EventAccumulator* other )
 {
 	mNumSamples = 0;
-	mSum = NaN;
+	mSum = 0;
 	mMin = NaN;
 	mMax = NaN;
 	mMean = NaN;
diff --git a/indra/llcommon/lltraceaccumulators.h b/indra/llcommon/lltraceaccumulators.h
index 2dcfdf48ad6d96221f7cc0c7197194472118b485..01f4ef506f6da2d837b7ca7d0628a3867e90af76 100644
--- a/indra/llcommon/lltraceaccumulators.h
+++ b/indra/llcommon/lltraceaccumulators.h
@@ -223,7 +223,7 @@ namespace LLTrace
 		typedef F64 value_t;
 
 		EventAccumulator()
-		:	mSum(NaN),
+		:	mSum(0),
 			mMin(NaN),
 			mMax(NaN),
 			mMean(NaN),
@@ -389,7 +389,7 @@ namespace LLTrace
 			mSum += value;
 		}
 
-		void addSamples(const CountAccumulator& other, bool /*follows_in_sequence*/)
+		void addSamples(const CountAccumulator& other, EBufferAppendType /*type*/)
 		{
 			mSum += other.mSum;
 			mNumSamples += other.mNumSamples;
@@ -515,8 +515,11 @@ namespace LLTrace
 
 		void addSamples(const MemStatAccumulator& other, EBufferAppendType append_type)
 		{
-			mAllocated.addSamples(other.mAllocated, append_type);
-			mDeallocated.addSamples(other.mDeallocated, append_type);
+			mFootprintAllocations.addSamples(other.mFootprintAllocations, append_type);
+			mFootprintDeallocations.addSamples(other.mFootprintDeallocations, append_type);
+			mShadowAllocations.addSamples(other.mShadowAllocations, append_type);
+			mShadowDeallocations.addSamples(other.mShadowDeallocations, append_type);
+
 			if (append_type == SEQUENTIAL)
 			{
 				mSize.addSamples(other.mSize, SEQUENTIAL);
@@ -524,12 +527,12 @@ namespace LLTrace
 			}
 			else
 			{
-				F64 allocation_delta(other.mAllocated.getSum() - other.mDeallocated.getSum());
+				F64 allocation_delta(other.mFootprintAllocations.getSum() - other.mFootprintDeallocations.getSum());
 				mSize.sample(mSize.hasValue() 
 					? mSize.getLastValue() + allocation_delta 
 					: allocation_delta);
 
-				F64 shadow_allocation_delta(other.mShadowAllocated.getSum() - other.mShadowDeallocated.getSum());
+				F64 shadow_allocation_delta(other.mShadowAllocations.getSum() - other.mShadowDeallocations.getSum());
 				mShadowSize.sample(mShadowSize.hasValue() 
 					? mShadowSize.getLastValue() + shadow_allocation_delta 
 					: shadow_allocation_delta);
@@ -540,10 +543,10 @@ namespace LLTrace
 		{
 			mSize.reset(other ? &other->mSize : NULL);
 			mShadowSize.reset(other ? &other->mShadowSize : NULL);
-			mAllocated.reset(other ? &other->mAllocated : NULL);
-			mDeallocated.reset(other ? &other->mDeallocated : NULL);
-			mShadowAllocated.reset(other ? &other->mShadowAllocated : NULL);
-			mShadowDeallocated.reset(other ? &other->mShadowDeallocated : NULL);
+			mFootprintAllocations.reset(other ? &other->mFootprintAllocations : NULL);
+			mFootprintDeallocations.reset(other ? &other->mFootprintDeallocations : NULL);
+			mShadowAllocations.reset(other ? &other->mShadowAllocations : NULL);
+			mShadowDeallocations.reset(other ? &other->mShadowDeallocations : NULL);
 		}
 
 		void sync(F64SecondsImplicit time_stamp) 
@@ -554,10 +557,10 @@ namespace LLTrace
 
 		SampleAccumulator	mSize,
 							mShadowSize;
-		CountAccumulator	mAllocated,
-							mDeallocated,
-							mShadowAllocated,
-							mShadowDeallocated;
+		EventAccumulator	mFootprintAllocations,
+							mShadowAllocations;
+		CountAccumulator	mFootprintDeallocations,
+							mShadowDeallocations;
 	};
 
 	struct AccumulatorBufferGroup : public LLRefCount
diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp
index ddf62845a07da87d37e96d4cc6dc315dd0b5bf05..fb2293844a37d29dd31ffbac4598aeaa1c1eac4b 100644
--- a/indra/llcommon/lltracerecording.cpp
+++ b/indra/llcommon/lltracerecording.cpp
@@ -230,62 +230,62 @@ F64Kilobytes Recording::getLastValue(const TraceType<MemStatAccumulator::ShadowM
 
 F64Kilobytes Recording::getSum(const TraceType<MemStatAccumulator::AllocationFacet>& stat)
 {
-	return F64Bytes(mBuffers->mMemStats[stat.getIndex()].mAllocated.getSum());
+	return F64Bytes(mBuffers->mMemStats[stat.getIndex()].mFootprintAllocations.getSum());
 }
 
 F64Kilobytes Recording::getPerSec(const TraceType<MemStatAccumulator::AllocationFacet>& stat)
 {
-	return F64Bytes(mBuffers->mMemStats[stat.getIndex()].mAllocated.getSum() / mElapsedSeconds.value());
+	return F64Bytes(mBuffers->mMemStats[stat.getIndex()].mFootprintAllocations.getSum() / mElapsedSeconds.value());
 }
 
 S32 Recording::getSampleCount(const TraceType<MemStatAccumulator::AllocationFacet>& stat)
 {
-	return mBuffers->mMemStats[stat.getIndex()].mAllocated.getSampleCount();
+	return mBuffers->mMemStats[stat.getIndex()].mFootprintAllocations.getSampleCount();
 }
 
 F64Kilobytes Recording::getSum(const TraceType<MemStatAccumulator::DeallocationFacet>& stat)
 {
-	return F64Bytes(mBuffers->mMemStats[stat.getIndex()].mDeallocated.getSum());
+	return F64Bytes(mBuffers->mMemStats[stat.getIndex()].mFootprintDeallocations.getSum());
 }
 
 F64Kilobytes Recording::getPerSec(const TraceType<MemStatAccumulator::DeallocationFacet>& stat)
 {
-	return F64Bytes(mBuffers->mMemStats[stat.getIndex()].mDeallocated.getSum() / mElapsedSeconds.value());
+	return F64Bytes(mBuffers->mMemStats[stat.getIndex()].mFootprintDeallocations.getSum() / mElapsedSeconds.value());
 }
 
 S32 Recording::getSampleCount(const TraceType<MemStatAccumulator::DeallocationFacet>& stat)
 {
-	return mBuffers->mMemStats[stat.getIndex()].mDeallocated.getSampleCount();
+	return mBuffers->mMemStats[stat.getIndex()].mFootprintDeallocations.getSampleCount();
 }
 
 F64Kilobytes Recording::getSum(const TraceType<MemStatAccumulator::ShadowAllocationFacet>& stat)
 {
-	return F64Bytes(mBuffers->mMemStats[stat.getIndex()].mShadowAllocated.getSum());
+	return F64Bytes(mBuffers->mMemStats[stat.getIndex()].mShadowAllocations.getSum());
 }
 
 F64Kilobytes Recording::getPerSec(const TraceType<MemStatAccumulator::ShadowAllocationFacet>& stat)
 {
-	return F64Bytes(mBuffers->mMemStats[stat.getIndex()].mShadowAllocated.getSum() / mElapsedSeconds.value());
+	return F64Bytes(mBuffers->mMemStats[stat.getIndex()].mShadowAllocations.getSum() / mElapsedSeconds.value());
 }
 
 S32 Recording::getSampleCount(const TraceType<MemStatAccumulator::ShadowAllocationFacet>& stat)
 {
-	return mBuffers->mMemStats[stat.getIndex()].mShadowAllocated.getSampleCount();
+	return mBuffers->mMemStats[stat.getIndex()].mShadowAllocations.getSampleCount();
 }
 
 F64Kilobytes Recording::getSum(const TraceType<MemStatAccumulator::ShadowDeallocationFacet>& stat)
 {
-	return F64Bytes(mBuffers->mMemStats[stat.getIndex()].mShadowDeallocated.getSum());
+	return F64Bytes(mBuffers->mMemStats[stat.getIndex()].mShadowDeallocations.getSum());
 }
 
 F64Kilobytes Recording::getPerSec(const TraceType<MemStatAccumulator::ShadowDeallocationFacet>& stat)
 {
-	return F64Bytes(mBuffers->mMemStats[stat.getIndex()].mShadowDeallocated.getSum() / mElapsedSeconds.value());
+	return F64Bytes(mBuffers->mMemStats[stat.getIndex()].mShadowDeallocations.getSum() / mElapsedSeconds.value());
 }
 
 S32 Recording::getSampleCount(const TraceType<MemStatAccumulator::ShadowDeallocationFacet>& stat)
 {
-	return mBuffers->mMemStats[stat.getIndex()].mShadowDeallocated.getSampleCount();
+	return mBuffers->mMemStats[stat.getIndex()].mShadowDeallocations.getSampleCount();
 }
 
 F64 Recording::getSum( const TraceType<CountAccumulator>& stat )