private long memoryAuditReport() {
        long companionOverHeads = 0;

        long bufferMem = 0;
        long maxMem = 0;
        int bufferCount = 0;
        for (ConcurrentHashMap<Integer, IntegerBuffer> map : buffers.values()) {
            companionOverHeads += 4;
            for(IntegerBuffer buf : map.values()) {
                bufferCount += 1;
                companionOverHeads += 4;
                long est = buf.memorySizeEst();
                bufferMem += est;
                maxMem = Math.max(maxMem, est);
            }
        }

        long distributionMem = 0;
        long maxDistMem = 0;
        long avoidMem = 0;
        int distCount = 0;
        for (ConcurrentHashMap<Integer, DiscreteDistribution> map : distributions.values()) {
            companionOverHeads += 4;
            for(DiscreteDistribution dist : map.values()) {
                distCount += 1;
                companionOverHeads += 4;
                long est = dist.memorySizeEst();
                distributionMem += est;
                maxDistMem = Math.max(est, maxDistMem);
                avoidMem += dist.avoidCount() * 6;
            }
        }

        NumberFormat nf = NumberFormat.getInstance(Locale.US);

        logger.info("======= MEMORY REPORT ======");
        logger.info("Companion internal: " + nf.format(companionOverHeads / 1024. / 1024.) + " mb");

        logger.info("Buffer mem: " + nf.format(bufferMem / 1024. / 1024.) + " mb");
        logger.info("Avg bytes per buffer: " +
                nf.format(bufferMem * 1.0 / bufferCount / 1024.) + " kb");
        logger.info("Max buffer was: " + nf.format(maxMem / 1024.) + "kb");

        logger.info("Distribution mem: " + nf.format(distributionMem / 1024. / 1024.) + " mb");
        logger.info("- of which avoids: " + nf.format(avoidMem / 1024. / 1024.) + " mb");

        logger.info("Avg bytes per distribution: " +
                nf.format((distributionMem * 1.0 / distCount / 1024.)) + " kb");
        logger.info("Max distribution: " + nf.format(maxDistMem / 1024.) + " kb");

        long totalMem = companionOverHeads + bufferMem + distributionMem;
        logger.info("** Total:  " + nf.format(totalMem / 1024. / 1024. / 1024.) +
                " GB (low-mem limit " +
                Runtime.getRuntime().maxMemory() * 0.75 / 1024. / 1024. / 1024. + "GB)" );
        isLowInMemory = totalMem > maxMemoryBytes;

        if (isLowInMemory) {
            compactMemoryUsage();
        }

        return totalMem;
    }