blob: bcf2320c3cc8719c308fdb80052ef03dd38a9571 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#include "kudu/server/tcmalloc_metrics.h"
#include <cstddef>
#include <cstdint>
#include <functional>
#include <ostream>
#include <glog/logging.h>
#ifdef TCMALLOC_ENABLED
#include <gperftools/malloc_extension.h>
#endif
#include "kudu/util/metrics.h"
#ifndef TCMALLOC_ENABLED
#define TCM_ASAN_MSG " (Disabled - no tcmalloc in this build)"
#else
#define TCM_ASAN_MSG
#endif
// As of this writing, we expose all of the un-deprecated tcmalloc status metrics listed at:
// http://gperftools.googlecode.com/svn/trunk/doc/tcmalloc.html
METRIC_DEFINE_gauge_uint64(server, generic_current_allocated_bytes,
"Heap Memory Usage", kudu::MetricUnit::kBytes,
"Number of bytes used by the application. This will not typically match the memory "
"use reported by the OS, because it does not include TCMalloc overhead or memory "
"fragmentation." TCM_ASAN_MSG,
kudu::MetricLevel::kInfo);
METRIC_DEFINE_gauge_uint64(server, generic_heap_size,
"Reserved Heap Memory", kudu::MetricUnit::kBytes,
"Bytes of system memory reserved by TCMalloc." TCM_ASAN_MSG,
kudu::MetricLevel::kInfo);
METRIC_DEFINE_gauge_uint64(server, tcmalloc_pageheap_free_bytes,
"Free Heap Memory", kudu::MetricUnit::kBytes,
"Number of bytes in free, mapped pages in page heap. These bytes can be used to "
"fulfill allocation requests. They always count towards virtual memory usage, and "
"unless the underlying memory is swapped out by the OS, they also count towards "
"physical memory usage." TCM_ASAN_MSG,
kudu::MetricLevel::kInfo);
METRIC_DEFINE_gauge_uint64(server, tcmalloc_pageheap_unmapped_bytes,
"Unmapped Heap Memory", kudu::MetricUnit::kBytes,
"Number of bytes in free, unmapped pages in page heap. These are bytes that have "
"been released back to the OS, possibly by one of the MallocExtension \"Release\" "
"calls. They can be used to fulfill allocation requests, but typically incur a page "
"fault. They always count towards virtual memory usage, and depending on the OS, "
"typically do not count towards physical memory usage." TCM_ASAN_MSG,
kudu::MetricLevel::kInfo);
METRIC_DEFINE_gauge_uint64(server, tcmalloc_max_total_thread_cache_bytes,
"Thread Cache Memory Limit", kudu::MetricUnit::kBytes,
"A limit to how much memory TCMalloc dedicates for small objects. Higher numbers "
"trade off more memory use for -- in some situations -- improved efficiency." TCM_ASAN_MSG,
kudu::MetricLevel::kInfo);
METRIC_DEFINE_gauge_uint64(server, tcmalloc_current_total_thread_cache_bytes,
"Thread Cache Memory Usage", kudu::MetricUnit::kBytes,
"A measure of some of the memory TCMalloc is using (for small objects)." TCM_ASAN_MSG,
kudu::MetricLevel::kInfo);
#undef TCM_ASAN_MSG
namespace kudu {
namespace tcmalloc {
static uint64_t GetTCMallocPropValue(const char* prop) {
size_t value = 0;
#ifdef TCMALLOC_ENABLED
if (!MallocExtension::instance()->GetNumericProperty(prop, &value)) {
LOG(DFATAL) << "Failed to get value of numeric tcmalloc property: " << prop;
}
#endif
return value;
}
void RegisterMetrics(const scoped_refptr<MetricEntity>& entity) {
entity->NeverRetire(
METRIC_generic_current_allocated_bytes.InstantiateFunctionGauge(
entity, []() {
return GetTCMallocPropValue("generic.current_allocated_bytes");
}));
entity->NeverRetire(
METRIC_generic_heap_size.InstantiateFunctionGauge(
entity, []() {
return GetTCMallocPropValue("generic.heap_size");
}));
entity->NeverRetire(
METRIC_tcmalloc_pageheap_free_bytes.InstantiateFunctionGauge(
entity, []() {
return GetTCMallocPropValue("tcmalloc.pageheap_free_bytes");
}));
entity->NeverRetire(
METRIC_tcmalloc_pageheap_unmapped_bytes.InstantiateFunctionGauge(
entity, []() {
return GetTCMallocPropValue("tcmalloc.pageheap_unmapped_bytes");
}));
entity->NeverRetire(
METRIC_tcmalloc_max_total_thread_cache_bytes.InstantiateFunctionGauge(
entity, []() {
return GetTCMallocPropValue("tcmalloc.max_total_thread_cache_bytes");
}));
entity->NeverRetire(
METRIC_tcmalloc_current_total_thread_cache_bytes.InstantiateFunctionGauge(
entity, []() {
return GetTCMallocPropValue("tcmalloc.current_total_thread_cache_bytes");
}));
}
} // namespace tcmalloc
} // namespace kudu