162 vsize =
t->current_->vsize;
164 rss =
t->current_->rss;
169 pss =
t->currentSmaps_.pss_;
240 void set(
double deltaV,
bool early);
276 std::ostringstream
t;
282 std::ostringstream
t;
311 ret.private_ +=
static_cast<double>(
value) / 1024.;
315 ret.pss_ +=
static_cast<double>(
value) / 1024.;
324 return (current - past) / (double)
count;
332 pg_size_(sysconf(_SC_PAGESIZE))
334 num_to_skip_(iPS.getUntrackedParameter<
int>(
"ignoreTotal")),
335 showMallocInfo_(iPS.getUntrackedParameter<
bool>(
"showMallocInfo")),
336 oncePerEventMode_(iPS.getUntrackedParameter<
bool>(
"oncePerEventMode")),
337 jobReportOutputOnly_(iPS.getUntrackedParameter<
bool>(
"jobReportOutputOnly")),
338 monitorPssAndPrivate_(iPS.getUntrackedParameter<
bool>(
"monitorPssAndPrivate")),
341 smapsLineBuffer_(nullptr),
342 smapsLineBufferLen_(0),
345 moduleSummaryRequested_(iPS.getUntrackedParameter<
bool>(
"moduleMemorySummary")),
346 measurementUnderway_(
false) {
349 std::ostringstream ost;
398 desc.addUntracked<
int>(
"ignoreTotal", 1);
399 desc.addUntracked<
bool>(
"showMallocInfo",
false);
400 desc.addUntracked<
bool>(
"oncePerEventMode",
false);
401 desc.addUntracked<
bool>(
"jobReportOutputOnly",
false);
402 desc.addUntracked<
bool>(
"monitorPssAndPrivate",
false);
403 desc.addUntracked<
bool>(
"moduleMemorySummary",
false);
404 desc.addUntracked<
bool>(
"dump",
false);
405 descriptions.
add(
"SimpleMemoryCheck",
desc);
411 std::ostringstream smapsNameOst;
412 smapsNameOst <<
"/proc/" << getpid() <<
"/smaps";
413 if ((
smapsFile_ = fopen(smapsNameOst.str().c_str(),
"r")) ==
nullptr) {
426 bool expected =
false;
428 std::shared_ptr<void> guard(
429 nullptr, [
this](
void const*) {
measurementUnderway_.store(
false, std::memory_order_release); });
435 bool expected =
false;
437 std::shared_ptr<void> guard(
438 nullptr, [
this](
void const*) {
measurementUnderway_.store(
false, std::memory_order_release); });
444 bool expected =
false;
446 std::shared_ptr<void> guard(
447 nullptr, [
this](
void const*) {
measurementUnderway_.store(
false, std::memory_order_release); });
453 bool expected =
false;
455 std::shared_ptr<void> guard(
456 nullptr, [
this](
void const*) {
measurementUnderway_.store(
false, std::memory_order_release); });
462 bool expected =
false;
464 std::shared_ptr<void> guard(
465 nullptr, [
this](
void const*) {
measurementUnderway_.store(
false, std::memory_order_release); });
473 <<
"MemoryReport> Peak virtual size " <<
eventT1_.
vsize <<
" Mbytes" 475 <<
" Key events increasing vsize: \n" 485 "\n Key events increasing rss:\n" 498 mmr <<
"ModuleMemoryReport> Each line has module label and: \n";
499 mmr <<
" (after early ignored events) \n";
500 mmr <<
" count of times module executed; average increase in vsize \n";
501 mmr <<
" maximum increase in vsize; event on which maximum occurred \n";
502 mmr <<
" (during early ignored events) \n";
503 mmr <<
" total and maximum vsize increases \n \n";
504 for (SignificantModulesMap::iterator im =
modules_.begin(); im !=
modules_.end(); ++im) {
506 if (
m.totalDeltaVsize == 0 &&
m.totalEarlyVsize == 0)
508 mmr << im->first <<
": ";
509 mmr <<
"n = " <<
m.postEarlyCount;
510 if (
m.postEarlyCount > 0) {
511 mmr <<
" avg = " <<
m.totalDeltaVsize /
m.postEarlyCount;
513 mmr <<
" max = " <<
m.maxDeltaVsize <<
" " <<
m.eventMaxDeltaV;
514 if (
m.totalEarlyVsize > 0) {
515 mmr <<
" early total: " <<
m.totalEarlyVsize;
516 mmr <<
" max: " <<
m.maxEarlyVsize;
524 #define SIMPLE_MEMORY_CHECK_ORIGINAL_XML_OUTPUT 525 #ifdef SIMPLE_MEMORY_CHECK_ORIGINAL_XML_OUTPUT 527 std::map<std::string, std::string> reportData;
560 #if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 33) 561 struct mallinfo2 minfo = mallinfo2();
563 struct mallinfo minfo = mallinfo();
565 reportData.insert(std::make_pair(
"HEAP_ARENA_SIZE_BYTES",
std::to_string(minfo.arena)));
566 reportData.insert(std::make_pair(
"HEAP_ARENA_N_UNUSED_CHUNKS",
std::to_string(minfo.ordblks)));
567 reportData.insert(std::make_pair(
"HEAP_TOP_FREE_BYTES",
std::to_string(minfo.keepcost)));
568 reportData.insert(std::make_pair(
"HEAP_MAPPED_SIZE_BYTES",
std::to_string(minfo.hblkhd)));
569 reportData.insert(std::make_pair(
"HEAP_MAPPED_N_CHUNKS",
std::to_string(minfo.hblks)));
570 reportData.insert(std::make_pair(
"HEAP_USED_BYTES",
std::to_string(minfo.uordblks)));
571 reportData.insert(std::make_pair(
"HEAP_UNUSED_BYTES",
std::to_string(minfo.fordblks)));
575 reportData.insert(std::make_pair(
"AverageGrowthRateVsize",
583 for (SignificantModulesMap::iterator im =
modules_.begin(); im !=
modules_.end(); ++im) {
585 if (
m.totalDeltaVsize == 0 &&
m.totalEarlyVsize == 0)
588 reportData.insert(std::make_pair(
label +
"PostEarlyCount",
i2str(
m.postEarlyCount)));
589 if (
m.postEarlyCount > 0) {
590 reportData.insert(std::make_pair(
label +
"AverageDeltaVsize",
d2str(
m.totalDeltaVsize /
m.postEarlyCount)));
592 reportData.insert(std::make_pair(
label +
"MaxDeltaVsize",
d2str(
m.maxDeltaVsize)));
593 if (
m.totalEarlyVsize > 0) {
594 reportData.insert(std::make_pair(
label +
"TotalEarlyVsize",
d2str(
m.totalEarlyVsize)));
595 reportData.insert(std::make_pair(
label +
"MaxEarlyDeltaVsize",
d2str(
m.maxEarlyVsize)));
600 std::map<std::string, std::string> reportMemoryProperties;
602 if (FILE* fmeminfo = fopen(
"/proc/meminfo",
"r")) {
606 while (fgets(
buf,
sizeof(
buf), fmeminfo)) {
608 char*
token =
nullptr;
609 token = strtok_r(
buf, space, &saveptr);
610 if (
token !=
nullptr) {
611 value = atol(strtok_r(
nullptr, space, &saveptr));
621 reportSvc->reportPerformanceSummary(
"ApplicationMemory", reportData);
622 reportSvc->reportPerformanceSummary(
"SystemMemory", reportMemoryProperties);
625 #ifdef SIMPLE_MEMORY_CHECK_DIFFERENT_XML_OUTPUT 626 std::vector<std::string> reportData;
658 #if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 33) 659 struct mallinfo2 minfo = mallinfo2();
661 struct mallinfo minfo = mallinfo();
663 reportData.push_back(
mallOutput(
"HEAP_ARENA_SIZE_BYTES", minfo.arena));
664 reportData.push_back(
mallOutput(
"HEAP_ARENA_N_UNUSED_CHUNKS", minfo.ordblks));
665 reportData.push_back(
mallOutput(
"HEAP_TOP_FREE_BYTES", minfo.keepcost));
666 reportData.push_back(
mallOutput(
"HEAP_MAPPED_SIZE_BYTES", minfo.hblkhd));
667 reportData.push_back(
mallOutput(
"HEAP_MAPPED_N_CHUNKS", minfo.hblks));
668 reportData.push_back(
mallOutput(
"HEAP_USED_BYTES", minfo.uordblks));
669 reportData.push_back(
mallOutput(
"HEAP_UNUSED_BYTES", minfo.fordblks));
672 reportData.insert(std::make_pair(
"AverageGrowthRateVsize",
679 reportSvc->reportMemoryInfo(reportData);
686 bool expected =
false;
688 std::shared_ptr<void> guard(
689 nullptr, [
this](
void const*) {
measurementUnderway_.store(
false, std::memory_order_release); });
704 bool expectedMeasurementUnderway =
false;
705 if (
measurementUnderway_.compare_exchange_strong(expectedMeasurementUnderway,
true, std::memory_order_acq_rel)) {
706 std::shared_ptr<void> guard(
707 nullptr, [
this](
void const*) {
measurementUnderway_.store(
false, std::memory_order_release); });
708 bool expectedModuleMeasurementUnderway =
false;
722 bool expected =
false;
724 std::shared_ptr<void> guard(
725 nullptr, [
this](
void const*) {
measurementUnderway_.store(
false, std::memory_order_release); });
737 std::shared_ptr<void> guardModuleMeasurementUnderway(
739 bool expected =
false;
741 std::shared_ptr<void> guardMeasurementUnderway(
742 nullptr, [
this](
void const*) {
measurementUnderway_.store(
false, std::memory_order_release); });
850 LogWarning(
"MemoryCheck") <<
"MemoryCheck: " <<
type <<
" " << mdname <<
":" << mdlabel <<
" VSIZE " 855 #if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 33) 856 struct mallinfo2 minfo = mallinfo2();
858 struct mallinfo minfo = mallinfo();
861 LogWarning(
"MemoryCheck") <<
"MemoryCheck: " <<
type <<
" " << mdname <<
":" << mdlabel <<
" VSIZE " 865 <<
" HEAP-ARENA [ SIZE-BYTES " << minfo.arena <<
" N-UNUSED-CHUNKS " 866 << minfo.ordblks <<
" TOP-FREE-BYTES " << minfo.keepcost <<
" ]" 867 <<
" HEAP-MAPPED [ SIZE-BYTES " << minfo.hblkhd <<
" N-CHUNKS " << minfo.hblks
869 <<
" HEAP-USED-BYTES " << minfo.uordblks <<
" HEAP-UNUSED-BYTES " 886 #ifdef SIMPLE_MEMORY_CHECK_ORIGINAL_XML_OUTPUT 889 std::map<std::string, std::string>&
m)
const {
891 std::ostringstream os;
892 os <<
title <<
"-a-COUNT";
893 m.insert(std::make_pair(os.str(),
i2str(
e.count)));
896 std::ostringstream os;
897 os <<
title <<
"-b-RUN";
898 m.insert(std::make_pair(os.str(),
d2str(static_cast<double>(
e.event.run()))));
901 std::ostringstream os;
902 os <<
title <<
"-c-EVENT";
903 m.insert(std::make_pair(os.str(),
d2str(static_cast<double>(
e.event.event()))));
906 std::ostringstream os;
907 os <<
title <<
"-d-VSIZE";
908 m.insert(std::make_pair(os.str(),
d2str(
e.vsize)));
911 std::ostringstream os;
912 os <<
title <<
"-e-DELTV";
913 m.insert(std::make_pair(os.str(),
d2str(
e.deltaVsize)));
916 std::ostringstream os;
917 os <<
title <<
"-f-RSS";
918 m.insert(std::make_pair(os.str(),
d2str(
e.rss)));
922 std::ostringstream os;
923 os <<
title <<
"-g-PRIVATE";
924 m.insert(std::make_pair(os.str(),
d2str(
e.privateSize)));
927 std::ostringstream os;
928 os <<
title <<
"-h-PSS";
929 m.insert(std::make_pair(os.str(),
d2str(
e.pss)));
935 #ifdef SIMPLE_MEMORY_CHECK_DIFFERENT_XML_OUTPUT 937 std::ostringstream os;
938 os <<
" <" <<
title <<
">\n";
939 os <<
" " <<
e.count <<
": " <<
e.event;
940 os <<
" vsize " <<
e.vsize -
e.deltaVsize <<
" + " <<
e.deltaVsize <<
" = " <<
e.vsize;
941 os <<
" rss: " <<
e.rss <<
"\n";
942 os <<
" </" <<
title <<
">\n";
947 std::ostringstream os;
948 os <<
" <" <<
title <<
">\n";
949 os <<
" " <<
n <<
"\n";
950 os <<
" </" <<
title <<
">\n";
959 m.totalEarlyVsize += dv;
960 if (dv >
m.maxEarlyVsize)
961 m.maxEarlyVsize = dv;
964 m.totalDeltaVsize += dv;
965 if (dv >
m.maxDeltaVsize) {
966 m.maxDeltaVsize = dv;
967 m.eventMaxDeltaV = currentEventID;
974 <<
" rss = " << se.
rss <<
" delta = " << se.
deltaRss;
998 #if defined(__linux__)
void watchPostModuleConstruction(PostModuleConstruction::slot_type const &iSlot)
static std::string i2str(int i)
ModuleDescription const * moduleDescription() const
SignificantEvent eventDeltaRssT1_
void preSourceConstruction(const ModuleDescription &)
std::pair< ALIstring, ALIstring > pss
friend std::ostream & operator<<(std::ostream &os, SimpleMemoryCheck::SignificantEvent const &se)
size_t smapsLineBufferLen_
void watchPostEndJob(PostEndJob::slot_type const &iSlot)
edm::propagate_const< ProcInfo * > current_
std::atomic< bool > measurementUnderway_
SignificantEvent eventT1_
void watchPreModuleEvent(PreModuleEvent::slot_type const &iSlot)
void updateEventStats(edm::EventID const &e)
ProcInfoFetcher piFetcher_
ret
prodAgent to be discontinued
void watchPostEvent(PostEvent::slot_type const &iSlot)
std::atomic< bool > moduleMeasurementUnderway_
std::string eventStatOutput(std::string title, SignificantEvent const &e) const
void watchPreSourceConstruction(PreSourceConstruction::slot_type const &iSlot)
void watchPostSourceConstruction(PostSourceConstruction::slot_type const &iSlot)
SignificantEvent eventRssT2_
SignificantEvent eventL1_
void watchPostModuleEvent(PostModuleEvent::slot_type const &iSlot)
std::string to_string(const V &value)
void watchPostSourceEvent(PostSourceEvent::slot_type const &iSlot)
std::string const & moduleName() const
SignificantEvent eventT3_
constexpr std::shared_ptr< T > & get_underlying_safe(propagate_const< std::shared_ptr< T >> &iP)
edm::EventID eventMaxDeltaV
std::atomic< unsigned int > moduleStreamID_
char *& smapsLineBuffer()
SignificantEvent eventRssT3_
edm::propagate_const< FILE * > smapsFile_
std::map< std::string, SignificantModule > SignificantModulesMap
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
StreamID const & streamID() const
bool operator==(const smapsInfo &p) const
friend struct SignificantEvent
std::ostream & operator<<(std::ostream &os, SimpleMemoryCheck::SignificantEvent const &se)
void set(double deltaV, double deltaR, edm::EventID const &e, SimpleMemoryCheck *t)
edm::propagate_const< ProcInfo * > previous_
bool monitorPssAndPrivate_
SignificantEvent eventR1_
SignificantEvent eventDeltaRssT3_
bool moduleSummaryRequested_
smapsInfo(double private_sz, double pss_sz)
bool jobReportOutputOnly_
#define DEFINE_FWK_SERVICE(type)
void updateAndPrint(const std::string &type, const std::string &mdlabel, const std::string &mdname)
void andPrint(const std::string &type, const std::string &mdlabel, const std::string &mdname) const
SignificantEvent eventR2_
void preModule(StreamContext const &, ModuleCallingContext const &)
char const * smapsLineBuffer() const
static std::string d2str(double d)
void add(std::string const &label, ParameterSetDescription const &psetDescription)
void updateModuleMemoryStats(SignificantModule &m, double dv, edm::EventID const &)
std::atomic< int > count_
SignificantEvent eventL2_
SignificantEvent eventDeltaRssT2_
void postEvent(StreamContext const &)
edm::propagate_const< char * > smapsLineBuffer_
EventID const & eventID() const
void watchPostModuleBeginJob(PostModuleBeginJob::slot_type const &iSlot)
void postSourceConstruction(const ModuleDescription &)
Log< level::System, true > LogAbsolute
SignificantEvent eventT2_
void postSourceEvent(StreamID)
void postModuleBeginJob(const ModuleDescription &)
unsigned int value() const
std::string mallOutput(std::string title, size_t const &n) const
double averageGrowthRate(double current, double past, int count)
Log< level::Warning, false > LogWarning
SimpleMemoryCheck(const ParameterSet &, ActivityRegistry &)
bool operator>(const smapsInfo &p) const
SignificantModulesMap modules_
SignificantEvent eventRssT1_
void postModule(StreamContext const &, ModuleCallingContext const &)
std::string const & moduleLabel() const
void postModuleConstruction(const ModuleDescription &)
bool monitorPssAndPrivate
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
void watchPostBeginJob(PostBeginJob::slot_type const &iSlot)
convenience function for attaching to signal
std::atomic< unsigned int > moduleID_