56 #include <boost/lexical_cast.hpp> 111 double averageGrowthRate(
double current,
double past,
int count);
163 rss(0), deltaRss(0), monitorPssAndPrivate(
false), privateSize(0), pss(0),event() {}
167 vsize =
t->current_->vsize;
169 rss =
t->current_->rss;
171 monitorPssAndPrivate =
t->monitorPssAndPrivate_;
172 if (monitorPssAndPrivate) {
173 privateSize =
t->currentSmaps_.private_;
174 pss =
t->currentSmaps_.pss_;
180 friend std::ostream &
operator<< (std::ostream & os,
232 std::map<std::string, std::string> &
m)
const;
244 , totalDeltaVsize (0)
247 , totalEarlyVsize (0)
248 , maxEarlyVsize (0) {}
249 void set (
double deltaV,
bool early);
252 friend std::ostream &
operator<< (std::ostream & os,
293 std::ostringstream
t;
299 std::ostringstream
t;
305 return piFetcher_.fetch();
313 fseek(smapsFile_, 0, SEEK_SET);
324 while ((read = getline(&smapsLineBuffer(), &smapsLineBufferLen_, smapsFile_)) != -1) {
327 if(0==strncmp(
"Private_",smapsLineBuffer_,8)) {
328 unsigned int value = atoi(smapsLineBuffer_+14);
331 }
else if(0==strncmp(
"Pss:",smapsLineBuffer_,4)) {
332 unsigned int value = atoi(smapsLineBuffer_+4);
334 ret.
pss_ +=
static_cast<double>(
value)/1024.;
343 return(current-past)/(double)count;
352 , pg_size_(sysconf(_SC_PAGESIZE))
353 , num_to_skip_(iPS.getUntrackedParameter<
int>(
"ignoreTotal"))
354 , showMallocInfo_(iPS.getUntrackedParameter<
bool>(
"showMallocInfo"))
355 , oncePerEventMode_(iPS.getUntrackedParameter<
bool>(
"oncePerEventMode"))
356 , jobReportOutputOnly_(iPS.getUntrackedParameter<
bool>(
"jobReportOutputOnly"))
357 , monitorPssAndPrivate_(iPS.getUntrackedParameter<
bool>(
"monitorPssAndPrivate"))
361 , smapsLineBufferLen_(0)
364 , moduleSummaryRequested_(iPS.getUntrackedParameter<
bool>(
"moduleMemorySummary"))
365 , measurementUnderway_(
false){
368 std::ostringstream ost;
402 #ifndef __SANITIZE_ADDRESS__ 421 <<
"ERROR: Problem with setting malloc options\n" 428 <<
"Malloc options: " << mo <<
"\n";
458 descriptions.
add(
"SimpleMemoryCheck", desc);
464 std::ostringstream smapsNameOst;
465 smapsNameOst <<
"/proc/"<<getpid()<<
"/smaps";
466 if((
smapsFile_ =fopen(smapsNameOst.str().c_str(),
"r"))==
nullptr) {
479 bool expected =
false;
481 std::shared_ptr<void> guard(
nullptr,[
this](
void const*) {
490 bool expected =
false;
492 std::shared_ptr<void> guard(
nullptr,[
this](
void const*) {
500 bool expected =
false;
502 std::shared_ptr<void> guard(
nullptr,[
this](
void const*) {
510 bool expected =
false;
512 std::shared_ptr<void> guard(
nullptr,[
this](
void const*) {
520 bool expected =
false;
522 std::shared_ptr<void> guard(
nullptr,[
this](
void const*) {
532 <<
"MemoryReport> Peak virtual size " <<
eventT1_.
vsize <<
" Mbytes" 534 <<
" Key events increasing vsize: \n" 548 mmr <<
"ModuleMemoryReport> Each line has module label and: \n";
549 mmr <<
" (after early ignored events) \n";
551 " count of times module executed; average increase in vsize \n";
553 " maximum increase in vsize; event on which maximum occurred \n";
554 mmr <<
" (during early ignored events) \n";
555 mmr <<
" total and maximum vsize increases \n \n";
556 for(SignificantModulesMap::iterator im =
modules_.begin();
560 mmr << im->first <<
": ";
576 #define SIMPLE_MEMORY_CHECK_ORIGINAL_XML_OUTPUT 577 #ifdef SIMPLE_MEMORY_CHECK_ORIGINAL_XML_OUTPUT 579 std::map<std::string, std::string> reportData;
612 struct mallinfo minfo = mallinfo();
614 std::make_pair(
"HEAP_ARENA_SIZE_BYTES",
i2str(minfo.arena)));
616 std::make_pair(
"HEAP_ARENA_N_UNUSED_CHUNKS",
i2str(minfo.ordblks)));
618 std::make_pair(
"HEAP_TOP_FREE_BYTES",
i2str(minfo.keepcost)));
620 std::make_pair(
"HEAP_MAPPED_SIZE_BYTES",
i2str(minfo.hblkhd)));
622 std::make_pair(
"HEAP_MAPPED_N_CHUNKS",
i2str(minfo.hblks)));
624 std::make_pair(
"HEAP_USED_BYTES",
i2str(minfo.uordblks)));
626 std::make_pair(
"HEAP_UNUSED_BYTES",
i2str(minfo.fordblks)));
640 for(SignificantModulesMap::iterator im =
modules_.begin();
647 reportData.insert(std::make_pair(label+
"AverageDeltaVsize",
653 reportData.insert(std::make_pair(label+
"MaxEarlyDeltaVsize",
d2str(m.
maxEarlyVsize)));
658 std::map<std::string, std::string> reportMemoryProperties;
660 if(FILE* fmeminfo = fopen(
"/proc/meminfo",
"r")) {
665 while(fgets(buf,
sizeof(buf), fmeminfo)) {
666 char* token =
nullptr;
667 token = strtok(buf, space);
668 if(token !=
nullptr) {
669 value = atol(strtok(
nullptr, space));
671 reportMemoryProperties.insert(std::make_pair(category.substr(0, strlen(token)-1),
i2str(value)));
679 reportSvc->reportPerformanceSummary(
"ApplicationMemory", reportData);
680 reportSvc->reportPerformanceSummary(
"SystemMemory", reportMemoryProperties);
683 #ifdef SIMPLE_MEMORY_CHECK_DIFFERENT_XML_OUTPUT 684 std::vector<std::string> reportData;
716 struct mallinfo minfo = mallinfo();
717 reportData.push_back(
718 mallOutput(
"HEAP_ARENA_SIZE_BYTES", minfo.arena));
719 reportData.push_back(
720 mallOutput(
"HEAP_ARENA_N_UNUSED_CHUNKS", minfo.ordblks));
721 reportData.push_back(
722 mallOutput(
"HEAP_TOP_FREE_BYTES", minfo.keepcost));
723 reportData.push_back(
724 mallOutput(
"HEAP_MAPPED_SIZE_BYTES", minfo.hblkhd));
725 reportData.push_back(
726 mallOutput(
"HEAP_MAPPED_N_CHUNKS", minfo.hblks));
727 reportData.push_back(
728 mallOutput(
"HEAP_USED_BYTES", minfo.uordblks));
729 reportData.push_back(
730 mallOutput(
"HEAP_UNUSED_BYTES", minfo.fordblks));
742 reportSvc->reportMemoryInfo(reportData);
749 bool expected =
false;
751 std::shared_ptr<void> guard(
nullptr,[
this](
void const*) {
768 bool expected =
false;
770 std::shared_ptr<void> guard(
nullptr,[
this](
void const*) {
773 bool expected =
false;
786 bool expected =
false;
788 std::shared_ptr<void> guard(
nullptr,[
this](
void const*) {
802 std::shared_ptr<void> guard(
nullptr,[
this](
void const*) {
805 bool expected =
false;
807 std::shared_ptr<void> guard(
nullptr,[
this](
void const*) {
916 <<
"MemoryCheck: " << type <<
" " 917 << mdname <<
":" << mdlabel
918 <<
" VSIZE " <<
current_->vsize <<
" " << deltaVSIZE
919 <<
" RSS " <<
current_->rss <<
" " << deltaRSS;
922 struct mallinfo minfo = mallinfo();
925 <<
"MemoryCheck: " << type <<
" " 926 << mdname <<
":" << mdlabel
927 <<
" VSIZE " <<
current_->vsize <<
" " << deltaVSIZE
928 <<
" RSS " <<
current_->rss <<
" " << deltaRSS
930 <<
" HEAP-ARENA [ SIZE-BYTES " << minfo.arena
931 <<
" N-UNUSED-CHUNKS " << minfo.ordblks
932 <<
" TOP-FREE-BYTES " << minfo.keepcost <<
" ]" 933 <<
" HEAP-MAPPED [ SIZE-BYTES " << minfo.hblkhd
934 <<
" N-CHUNKS " << minfo.hblks <<
" ]" 935 <<
" HEAP-USED-BYTES " << minfo.uordblks
936 <<
" HEAP-UNUSED-BYTES " << minfo.fordblks
951 #ifdef SIMPLE_MEMORY_CHECK_ORIGINAL_XML_OUTPUT 955 std::map<std::string, std::string>&
m)
const {
956 { std::ostringstream os;
957 os << title <<
"-a-COUNT";
958 m.insert(std::make_pair(os.str(),
i2str(e.
count))); }
959 { std::ostringstream os;
960 os << title <<
"-b-RUN";
961 m.insert(std::make_pair(os.str(),
d2str(static_cast<double>(e.
event.
run())))); }
962 { std::ostringstream os;
963 os << title <<
"-c-EVENT";
964 m.insert(std::make_pair(os.str(),
d2str(static_cast<double>(e.
event.
event())))); }
965 { std::ostringstream os;
966 os << title <<
"-d-VSIZE";
967 m.insert(std::make_pair(os.str(),
d2str(e.
vsize))); }
968 { std::ostringstream os;
969 os << title <<
"-e-DELTV";
971 { std::ostringstream os;
972 os << title <<
"-f-RSS";
973 m.insert(std::make_pair(os.str(),
d2str(e.
rss))); }
975 { std::ostringstream os;
976 os << title <<
"-g-PRIVATE";
978 { std::ostringstream os;
979 os << title <<
"-h-PSS";
980 m.insert(std::make_pair(os.str(),
d2str(e.
pss))); }
985 #ifdef SIMPLE_MEMORY_CHECK_DIFFERENT_XML_OUTPUT 989 std::ostringstream os;
990 os <<
" <" << title <<
">\n";
994 os <<
" rss: " << e.
rss <<
"\n";
995 os <<
" </" << title <<
">\n";
1001 std::ostringstream os;
1002 os <<
" <" << title <<
">\n";
1003 os <<
" " << n <<
"\n";
1004 os <<
" </" << title <<
">\n";
1028 os <<
"[" << se.
count <<
"] " 1031 <<
" rss = " << se.
rss <<
" delta = " << se.
deltaRss;
1060 #if defined(__linux__)
void watchPostModuleConstruction(PostModuleConstruction::slot_type const &iSlot)
std::map< std::string, SignificantModule > SignificantModulesMap
EventNumber_t event() const
T getUntrackedParameter(std::string const &, T const &) const
void set_trim_thr(opt_type trim_thr)
static std::string i2str(int i)
std::string eventStatOutput(std::string title, SignificantEvent const &e) const
SignificantEvent eventDeltaRssT1_
void preSourceConstruction(const ModuleDescription &)
void set_mmap_max(opt_type mmap_max)
friend std::ostream & operator<<(std::ostream &os, SimpleMemoryCheck::SignificantEvent const &se)
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
size_t smapsLineBufferLen_
void watchPostEndJob(PostEndJob::slot_type const &iSlot)
edm::propagate_const< ProcInfo * > current_
std::atomic< bool > measurementUnderway_
SignificantEvent eventT1_
void set_mmap_thr(opt_type mmap_thr)
void watchPreModuleEvent(PreModuleEvent::slot_type const &iSlot)
void updateEventStats(edm::EventID const &e)
ProcInfoFetcher piFetcher_
void watchPostEvent(PostEvent::slot_type const &iSlot)
std::atomic< bool > moduleMeasurementUnderway_
void watchPreSourceConstruction(PreSourceConstruction::slot_type const &iSlot)
void watchPostSourceConstruction(PostSourceConstruction::slot_type const &iSlot)
SignificantEvent eventRssT2_
SignificantEvent eventL1_
std::string const & moduleName() const
void watchPostModuleEvent(PostModuleEvent::slot_type const &iSlot)
void watchPostSourceEvent(PostSourceEvent::slot_type const &iSlot)
SignificantEvent eventT3_
std::string const & moduleLabel() const
edm::EventID eventMaxDeltaV
void andPrint(const std::string &type, const std::string &mdlabel, const std::string &mdname) const
std::atomic< unsigned int > moduleStreamID_
char *& smapsLineBuffer()
SignificantEvent eventRssT3_
edm::propagate_const< FILE * > smapsFile_
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
ModuleDescription const * moduleDescription() const
char const * smapsLineBuffer() const
std::shared_ptr< T > & get_underlying_safe(propagate_const< std::shared_ptr< T >> &iP)
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_
StreamID const & streamID() const
bool moduleSummaryRequested_
double deltaR(double eta1, double eta2, double phi1, double phi2)
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)
bool operator==(const smapsInfo &p) const
unsigned int value() const
SignificantEvent eventR2_
void preModule(StreamContext const &, ModuleCallingContext 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_
std::string error_message() const
SignificantEvent eventL2_
SignificantEvent eventDeltaRssT2_
void postEvent(StreamContext const &)
std::string mallOutput(std::string title, size_t const &n) const
edm::propagate_const< char * > smapsLineBuffer_
void watchPostModuleBeginJob(PostModuleBeginJob::slot_type const &iSlot)
void adjustMallocParams()
void postSourceConstruction(const ModuleDescription &)
SignificantEvent eventT2_
void postSourceEvent(StreamID)
EventID const & eventID() const
void postModuleBeginJob(const ModuleDescription &)
double averageGrowthRate(double current, double past, int count)
void set_top_pad(opt_type top_pad)
SimpleMemoryCheck(const ParameterSet &, ActivityRegistry &)
SignificantModulesMap modules_
SignificantEvent eventRssT1_
void postModule(StreamContext const &, ModuleCallingContext const &)
std::pair< std::string, std::shared_ptr< void > > fetch(const cond::Hash &payloadId, Session &session)
void postModuleConstruction(const ModuleDescription &)
bool operator>(const smapsInfo &p) const
bool monitorPssAndPrivate
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
MallocOptionSetter & getGlobalOptionSetter()
void watchPostBeginJob(PostBeginJob::slot_type const &iSlot)
convenience function for attaching to signal
std::atomic< unsigned int > moduleID_