uint64 DLAllocator::GetMemoryUsage() { return dlmalloc_footprint(); }
void dvmLogGcStats(size_t numFreed, size_t sizeFreed, size_t gcTimeMs) { size_t perHeapActualSize[HEAP_SOURCE_MAX_HEAP_COUNT], perHeapAllowedSize[HEAP_SOURCE_MAX_HEAP_COUNT], perHeapNumAllocated[HEAP_SOURCE_MAX_HEAP_COUNT], perHeapSizeAllocated[HEAP_SOURCE_MAX_HEAP_COUNT]; unsigned char eventBuf[1 + (1 + sizeof(long long)) * 4]; size_t actualSize, allowedSize, numAllocated, sizeAllocated; size_t softLimit = dvmHeapSourceGetIdealFootprint(); size_t nHeaps = dvmHeapSourceGetNumHeaps(); /* Enough to quiet down gcc for unitialized variable check */ perHeapActualSize[0] = perHeapAllowedSize[0] = perHeapNumAllocated[0] = perHeapSizeAllocated[0] = 0; actualSize = dvmHeapSourceGetValue(HS_FOOTPRINT, perHeapActualSize, HEAP_SOURCE_MAX_HEAP_COUNT); allowedSize = dvmHeapSourceGetValue(HS_ALLOWED_FOOTPRINT, perHeapAllowedSize, HEAP_SOURCE_MAX_HEAP_COUNT); numAllocated = dvmHeapSourceGetValue(HS_OBJECTS_ALLOCATED, perHeapNumAllocated, HEAP_SOURCE_MAX_HEAP_COUNT); sizeAllocated = dvmHeapSourceGetValue(HS_BYTES_ALLOCATED, perHeapSizeAllocated, HEAP_SOURCE_MAX_HEAP_COUNT); /* * Construct the the first 64-bit value to write to the log. * Global information: * * [63 ] Must be zero * [62-24] ASCII process identifier * [23-12] GC time in ms * [11- 0] Bytes freed * */ long long event0; event0 = 0LL << 63 | (long long)intToFloat12(gcTimeMs) << 12 | (long long)intToFloat12(sizeFreed); insertProcessName(&event0); /* * Aggregated heap stats: * * [63-62] 10 * [61-60] Reserved; must be zero * [59-48] Objects freed * [47-36] Actual size (current footprint) * [35-24] Allowed size (current hard max) * [23-12] Objects allocated * [11- 0] Bytes allocated */ long long event1; event1 = 2LL << 62 | (long long)intToFloat12(numFreed) << 48 | (long long)intToFloat12(actualSize) << 36 | (long long)intToFloat12(allowedSize) << 24 | (long long)intToFloat12(numAllocated) << 12 | (long long)intToFloat12(sizeAllocated); /* * Report the current state of the zygote heap(s). * * The active heap is always heap[0]. We can be in one of three states * at present: * * (1) Still in the zygote. Zygote using heap[0]. * (2) In the zygote, when the first child is started. We created a * new heap just before the first fork() call, so the original * "zygote heap" is now heap[1], and we have a small heap[0] for * anything we do from here on. * (3) In an app process. The app gets a new heap[0], and can also * see the two zygote heaps [1] and [2] (probably unwise to * assume any specific ordering). * * So if nHeaps == 1, we want the stats from heap[0]; else we want * the sum of the values from heap[1] to heap[nHeaps-1]. * * * Zygote heap stats (except for the soft limit, which belongs to the * active heap): * * [63-62] 11 * [61-60] Reserved; must be zero * [59-48] Soft Limit (for the active heap) * [47-36] Actual size (current footprint) * [35-24] Allowed size (current hard max) * [23-12] Objects allocated * [11- 0] Bytes allocated */ long long event2; size_t zActualSize, zAllowedSize, zNumAllocated, zSizeAllocated; int firstHeap = (nHeaps == 1) ? 0 : 1; size_t hh; zActualSize = zAllowedSize = zNumAllocated = zSizeAllocated = 0; for (hh = firstHeap; hh < nHeaps; hh++) { zActualSize += perHeapActualSize[hh]; zAllowedSize += perHeapAllowedSize[hh]; zNumAllocated += perHeapNumAllocated[hh]; zSizeAllocated += perHeapSizeAllocated[hh]; } event2 = 3LL << 62 | (long long)intToFloat12(softLimit) << 48 | (long long)intToFloat12(zActualSize) << 36 | (long long)intToFloat12(zAllowedSize) << 24 | (long long)intToFloat12(zNumAllocated) << 12 | (long long)intToFloat12(zSizeAllocated); /* * Report the current external allocation stats and the native heap * summary. * * [63-48] Reserved; must be zero (TODO: put new data in these slots) * [47-36] dlmalloc_footprint * [35-24] mallinfo: total allocated space * [23-12] External byte limit * [11- 0] External bytes allocated */ long long event3; size_t externalLimit, externalBytesAllocated; size_t uordblks, footprint; #if 0 /* * This adds 2-5msec to the GC cost on a DVT, or about 2-3% of the cost * of a GC, so it's not horribly expensive but it's not free either. */ extern size_t dlmalloc_footprint(void); struct mallinfo mi; //u8 start, end; //start = dvmGetRelativeTimeNsec(); mi = mallinfo(); uordblks = mi.uordblks; footprint = dlmalloc_footprint(); //end = dvmGetRelativeTimeNsec(); //LOGD("mallinfo+footprint took %dusec; used=%zd footprint=%zd\n", // (int)((end - start) / 1000), mi.uordblks, footprint); #else uordblks = footprint = 0; #endif externalLimit = dvmHeapSourceGetValue(HS_EXTERNAL_LIMIT, NULL, 0); externalBytesAllocated = dvmHeapSourceGetValue(HS_EXTERNAL_BYTES_ALLOCATED, NULL, 0); event3 = (long long)intToFloat12(footprint) << 36 | (long long)intToFloat12(uordblks) << 24 | (long long)intToFloat12(externalLimit) << 12 | (long long)intToFloat12(externalBytesAllocated); /* Build the event data. * [ 0: 0] item count (4) * [ 1: 1] EVENT_TYPE_LONG * [ 2: 9] event0 * [10:10] EVENT_TYPE_LONG * [11:18] event1 * [19:19] EVENT_TYPE_LONG * [20:27] event2 * [28:28] EVENT_TYPE_LONG * [29:36] event2 */ unsigned char *c = eventBuf; *c++ = 4; *c++ = EVENT_TYPE_LONG; memcpy(c, &event0, sizeof(event0)); c += sizeof(event0); *c++ = EVENT_TYPE_LONG; memcpy(c, &event1, sizeof(event1)); c += sizeof(event1); *c++ = EVENT_TYPE_LONG; memcpy(c, &event2, sizeof(event2)); c += sizeof(event2); *c++ = EVENT_TYPE_LONG; memcpy(c, &event3, sizeof(event3)); (void) android_btWriteLog(EVENT_LOG_TAG_dvm_gc_info, EVENT_TYPE_LIST, eventBuf, sizeof(eventBuf)); }