mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-23 16:55:09 +00:00
191 lines
7.6 KiB
C++
191 lines
7.6 KiB
C++
/*
|
|
* Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
|
|
* Copyright (c) 2023, 2024, Red Hat, Inc. and/or its affiliates.
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
* accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU General Public License version
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
* questions.
|
|
*
|
|
*/
|
|
|
|
#include "nmt/memMapPrinter.hpp"
|
|
#include "procMapsParser.hpp"
|
|
#include "runtime/os.hpp"
|
|
#include "utilities/align.hpp"
|
|
#include "utilities/globalDefinitions.hpp"
|
|
#include "utilities/ostream.hpp"
|
|
#include "utilities/powerOfTwo.hpp"
|
|
|
|
#include <limits.h>
|
|
|
|
class ProcSmapsSummary {
|
|
unsigned _num_mappings;
|
|
size_t _vsize; // combined virtual size
|
|
size_t _rss; // combined resident set size
|
|
size_t _committed; // combined committed size
|
|
size_t _shared; // combined shared size
|
|
size_t _swapped_out; // combined amount of swapped-out memory
|
|
size_t _hugetlb; // combined amount of memory backed by explicit huge pages
|
|
size_t _thp; // combined amount of memory backed by THPs
|
|
public:
|
|
ProcSmapsSummary() : _num_mappings(0), _vsize(0), _rss(0), _committed(0), _shared(0),
|
|
_swapped_out(0), _hugetlb(0), _thp(0) {}
|
|
void add_mapping(const ProcSmapsInfo& info) {
|
|
_num_mappings++;
|
|
_vsize += info.vsize();
|
|
_rss += info.rss;
|
|
_committed += info.nr ? 0 : info.vsize();
|
|
_shared += info.sh ? info.vsize() : 0;
|
|
_swapped_out += info.swap;
|
|
_hugetlb += info.private_hugetlb + info.shared_hugetlb;
|
|
_thp += info.anonhugepages;
|
|
}
|
|
|
|
void print_on(const MappingPrintSession& session) const {
|
|
outputStream* st = session.out();
|
|
st->print_cr("Number of mappings: %u", _num_mappings);
|
|
st->print_cr(" vsize: %zu (" PROPERFMT ")", _vsize, PROPERFMTARGS(_vsize));
|
|
st->print_cr(" rss: %zu (" PROPERFMT ")", _rss, PROPERFMTARGS(_rss));
|
|
st->print_cr(" committed: %zu (" PROPERFMT ")", _committed, PROPERFMTARGS(_committed));
|
|
st->print_cr(" shared: %zu (" PROPERFMT ")", _shared, PROPERFMTARGS(_shared));
|
|
st->print_cr(" swapped out: %zu (" PROPERFMT ")", _swapped_out, PROPERFMTARGS(_swapped_out));
|
|
st->print_cr(" using thp: %zu (" PROPERFMT ")", _thp, PROPERFMTARGS(_thp));
|
|
st->print_cr(" hugetlb: %zu (" PROPERFMT ")", _hugetlb, PROPERFMTARGS(_hugetlb));
|
|
}
|
|
};
|
|
|
|
class ProcSmapsPrinter {
|
|
const MappingPrintSession& _session;
|
|
public:
|
|
ProcSmapsPrinter(const MappingPrintSession& session) :
|
|
_session(session)
|
|
{}
|
|
|
|
void print_single_mapping(const ProcSmapsInfo& info) const {
|
|
outputStream* st = _session.out();
|
|
#define INDENT_BY(n) \
|
|
if (st->fill_to(n) == 0) { \
|
|
st->print(" "); \
|
|
}
|
|
st->print(PTR_FORMAT "-" PTR_FORMAT, p2i(info.from), p2i(info.to));
|
|
INDENT_BY(38);
|
|
st->print("%12zu", info.vsize());
|
|
INDENT_BY(51);
|
|
st->print("%s", info.prot);
|
|
INDENT_BY(56);
|
|
st->print("%12zu", info.rss);
|
|
INDENT_BY(69);
|
|
st->print("%12zu", info.private_hugetlb);
|
|
INDENT_BY(82);
|
|
st->print(EXACTFMT, EXACTFMTARGS(info.kernelpagesize));
|
|
{
|
|
INDENT_BY(87);
|
|
int num_printed = 0;
|
|
#define PRINTIF(cond, s) \
|
|
if (cond) { \
|
|
st->print("%s%s", (num_printed > 0 ? "," : ""), s); \
|
|
num_printed++; \
|
|
}
|
|
PRINTIF(info.sh, "shrd");
|
|
PRINTIF(!info.nr, "com");
|
|
PRINTIF(info.swap > 0, "swap");
|
|
PRINTIF(info.ht, "huge");
|
|
PRINTIF(info.anonhugepages > 0, "thp");
|
|
PRINTIF(info.thpeligible, "thpel");
|
|
PRINTIF(info.hg, "thpad");
|
|
PRINTIF(info.nh, "nothp");
|
|
if (num_printed == 0) {
|
|
st->print("-");
|
|
}
|
|
#undef PRINTIF
|
|
}
|
|
INDENT_BY(104);
|
|
if (!_session.print_nmt_info_for_region(info.from, info.to)) {
|
|
st->print("-");
|
|
}
|
|
INDENT_BY(142);
|
|
st->print_raw(info.filename[0] == '\0' ? "-" : info.filename);
|
|
#undef INDENT_BY
|
|
st->cr();
|
|
}
|
|
|
|
void print_legend() const {
|
|
outputStream* st = _session.out();
|
|
st->print_cr("from, to, vsize: address range and size");
|
|
st->print_cr("prot: protection");
|
|
st->print_cr("rss: resident set size");
|
|
st->print_cr("hugetlb: size of private hugetlb pages");
|
|
st->print_cr("pgsz: page size");
|
|
st->print_cr("notes: mapping information (detail mode only)");
|
|
st->print_cr(" shrd: mapping is shared");
|
|
st->print_cr(" com: mapping committed (swap space reserved)");
|
|
st->print_cr(" swap: mapping partly or completely swapped out");
|
|
st->print_cr(" thp: mapping uses THP");
|
|
st->print_cr(" thpel: mapping is THP-eligible");
|
|
st->print_cr(" thpad: mapping is THP-madvised");
|
|
st->print_cr(" nothp: mapping is forbidden to use THP");
|
|
st->print_cr(" huge: mapping uses hugetlb pages");
|
|
st->print_cr("vm info: VM information (requires NMT)");
|
|
{
|
|
StreamIndentor si(st, 16);
|
|
_session.print_nmt_flag_legend();
|
|
}
|
|
st->print_cr("file: file mapped, if mapping is not anonymous");
|
|
}
|
|
|
|
void print_header() const {
|
|
outputStream* st = _session.out();
|
|
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7
|
|
// 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
|
|
// 0x0000000414000000-0x0000000453000000 123456789012 rw-p 123456789012 123456789012 16g thp,thpadv STACK-340754-Monitor-Deflation-Thread /shared/tmp.txt
|
|
st->print_cr("from to vsize prot rss hugetlb pgsz notes info file");
|
|
st->print_cr("========================================================================================================================================================================");
|
|
}
|
|
};
|
|
|
|
void MemMapPrinter::pd_print_all_mappings(const MappingPrintSession& session) {
|
|
constexpr char filename[] = "/proc/self/smaps";
|
|
FILE* f = os::fopen(filename, "r");
|
|
if (f == nullptr) {
|
|
session.out()->print_cr("Cannot open %s", filename);
|
|
return;
|
|
}
|
|
|
|
ProcSmapsPrinter printer(session);
|
|
ProcSmapsSummary summary;
|
|
|
|
outputStream* const st = session.out();
|
|
|
|
printer.print_legend();
|
|
st->cr();
|
|
printer.print_header();
|
|
|
|
ProcSmapsInfo info;
|
|
ProcSmapsParser parser(f);
|
|
while (parser.parse_next(info)) {
|
|
printer.print_single_mapping(info);
|
|
summary.add_mapping(info);
|
|
}
|
|
st->cr();
|
|
|
|
summary.print_on(session);
|
|
st->cr();
|
|
|
|
::fclose(f);
|
|
}
|