00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "FWCore/Services/src/Memory.h"
00022 #include "DataFormats/Provenance/interface/ModuleDescription.h"
00023 #include "FWCore/Framework/interface/Event.h"
00024 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00025 #include "FWCore/MessageLogger/interface/JobReport.h"
00026 #include "FWCore/ServiceRegistry/interface/ActivityRegistry.h"
00027 #include "FWCore/ServiceRegistry/interface/Service.h"
00028 #include "FWCore/Utilities/interface/Exception.h"
00029 #include "FWCore/Utilities/interface/MallocOpts.h"
00030
00031 #include <malloc.h>
00032 #include <sstream>
00033 #include <iostream>
00034
00035 #ifdef __linux__
00036 #define LINUX 1
00037 #endif
00038
00039 #include <unistd.h>
00040 #include <fcntl.h>
00041
00042 namespace edm {
00043 namespace service {
00044
00045
00046 struct linux_proc {
00047 int pid;
00048 char comm[400];
00049 char state;
00050 int ppid;
00051 int pgrp;
00052 int session;
00053 int tty;
00054 int tpgid;
00055 unsigned int flags;
00056 unsigned int minflt;
00057 unsigned int cminflt;
00058 unsigned int majflt;
00059 unsigned int cmajflt;
00060 int utime;
00061 int stime;
00062 int cutime;
00063 int cstime;
00064 int counter;
00065 int priority;
00066 unsigned int timeout;
00067 unsigned int itrealvalue;
00068 int starttime;
00069 unsigned int vsize;
00070 unsigned int rss;
00071 unsigned int rlim;
00072 unsigned int startcode;
00073 unsigned int endcode;
00074 unsigned int startstack;
00075 unsigned int kstkesp;
00076 unsigned int kstkeip;
00077 int signal;
00078 int blocked;
00079 int sigignore;
00080 int sigcatch;
00081 unsigned int wchan;
00082 };
00083
00084 procInfo SimpleMemoryCheck::fetch()
00085 {
00086 procInfo ret;
00087 double pr_size=0.0, pr_rssize=0.0;
00088
00089 #ifdef LINUX
00090 linux_proc pinfo;
00091 int cnt;
00092
00093 lseek(fd_,0,SEEK_SET);
00094
00095 if((cnt=read(fd_,buf_,sizeof(buf_)))<0)
00096 {
00097 perror("Read of Proc file failed:");
00098 return procInfo();
00099 }
00100
00101 if(cnt>0)
00102 {
00103 buf_[cnt]='\0';
00104
00105 sscanf(buf_,
00106 "%d %s %c %d %d %d %d %d %u %u %u %u %u %d %d %d %d %d %d %u %u %d %u %u %u %u %u %u %u %u %d %d %d %d %u",
00107 &pinfo.pid,
00108 pinfo.comm,
00109 &pinfo.state,
00110 &pinfo.ppid,
00111 &pinfo.pgrp,
00112 &pinfo.session,
00113 &pinfo.tty,
00114 &pinfo.tpgid,
00115 &pinfo.flags,
00116 &pinfo.minflt,
00117 &pinfo.cminflt,
00118 &pinfo.majflt,
00119 &pinfo.cmajflt,
00120 &pinfo.utime,
00121 &pinfo.stime,
00122 &pinfo.cutime,
00123 &pinfo.cstime,
00124 &pinfo.counter,
00125 &pinfo.priority,
00126 &pinfo.timeout,
00127 &pinfo.itrealvalue,
00128 &pinfo.starttime,
00129 &pinfo.vsize,
00130 &pinfo.rss,
00131 &pinfo.rlim,
00132 &pinfo.startcode,
00133 &pinfo.endcode,
00134 &pinfo.startstack,
00135 &pinfo.kstkesp,
00136 &pinfo.kstkeip,
00137 &pinfo.signal,
00138 &pinfo.blocked,
00139 &pinfo.sigignore,
00140 &pinfo.sigcatch,
00141 &pinfo.wchan
00142 );
00143
00144
00145 pr_size = (double)pinfo.vsize;
00146 pr_rssize = (double)pinfo.rss;
00147
00148 ret.vsize = pr_size / (1024.0*1024.0);
00149 ret.rss = (pr_rssize * pg_size_) / (1024.0*1024.0);
00150 }
00151 #else
00152 ret.vsize=0;
00153 ret.rss=0;
00154 #endif
00155 return ret;
00156 }
00157
00158 SimpleMemoryCheck::SimpleMemoryCheck(const ParameterSet& iPS,
00159 ActivityRegistry&iReg)
00160 : a_()
00161 , b_()
00162 , current_(&a_)
00163 , previous_(&b_)
00164 , pg_size_(sysconf(_SC_PAGESIZE))
00165 , num_to_skip_(iPS.getUntrackedParameter<int>("ignoreTotal",1))
00166 , showMallocInfo(iPS.getUntrackedParameter<bool>("showMallocInfo",false))
00167 , oncePerEventMode
00168 (iPS.getUntrackedParameter<bool>("oncePerEventMode",false))
00169 , count_()
00170 , moduleSummaryRequested
00171 (iPS.getUntrackedParameter<bool>("moduleMemorySummary",false))
00172
00173 {
00174
00175 std::ostringstream ost;
00176
00177 #ifdef LINUX
00178 ost << "/proc/" << getpid() << "/stat";
00179 fname_ = ost.str();
00180
00181 if((fd_=open(ost.str().c_str(),O_RDONLY))<0)
00182 {
00183 throw edm::Exception(errors::Configuration)
00184 << "Memory checker server: Failed to open " << ost.str() << std::endl;
00185 }
00186 #endif
00187 if (!oncePerEventMode) {
00188 iReg.watchPreSourceConstruction(this,
00189 &SimpleMemoryCheck::preSourceConstruction);
00190 iReg.watchPostSourceConstruction(this,
00191 &SimpleMemoryCheck::postSourceConstruction);
00192 iReg.watchPostSource(this,
00193 &SimpleMemoryCheck::postSource);
00194 iReg.watchPostModuleConstruction(this,
00195 &SimpleMemoryCheck::postModuleConstruction);
00196 iReg.watchPostModuleBeginJob(this,
00197 &SimpleMemoryCheck::postModuleBeginJob);
00198 iReg.watchPostProcessEvent(this,
00199 &SimpleMemoryCheck::postEventProcessing);
00200 iReg.watchPostModule(this,
00201 &SimpleMemoryCheck::postModule);
00202 iReg.watchPostEndJob(this,
00203 &SimpleMemoryCheck::postEndJob);
00204 } else {
00205 iReg.watchPostProcessEvent(this,
00206 &SimpleMemoryCheck::postEventProcessing);
00207 iReg.watchPostEndJob(this,
00208 &SimpleMemoryCheck::postEndJob);
00209 }
00210 if (moduleSummaryRequested) {
00211 iReg.watchPreProcessEvent(this,
00212 &SimpleMemoryCheck::preEventProcessing);
00213 iReg.watchPreModule(this,
00214 &SimpleMemoryCheck::preModule);
00215 if (oncePerEventMode) {
00216 iReg.watchPostModule(this,
00217 &SimpleMemoryCheck::postModule);
00218 }
00219 }
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230 typedef edm::MallocOpts::opt_type opt_type;
00231 edm::MallocOptionSetter& mopts = edm::getGlobalOptionSetter();
00232
00233 opt_type
00234 p_mmap_max=iPS.getUntrackedParameter<opt_type>("M_MMAP_MAX",-1),
00235 p_trim_thr=iPS.getUntrackedParameter<opt_type>("M_TRIM_THRESHOLD",-1),
00236 p_top_pad=iPS.getUntrackedParameter<opt_type>("M_TOP_PAD",-1),
00237 p_mmap_thr=iPS.getUntrackedParameter<opt_type>("M_MMAP_THRESHOLD",-1);
00238
00239 if(p_mmap_max>=0) mopts.set_mmap_max(p_mmap_max);
00240 if(p_trim_thr>=0) mopts.set_trim_thr(p_trim_thr);
00241 if(p_top_pad>=0) mopts.set_top_pad(p_top_pad);
00242 if(p_mmap_thr>=0) mopts.set_mmap_thr(p_mmap_thr);
00243
00244 mopts.adjustMallocParams();
00245
00246 if(mopts.hasErrors())
00247 {
00248 LogWarning("MemoryCheck")
00249 << "ERROR: Problem with setting malloc options\n"
00250 << mopts.error_message();
00251 }
00252
00253 if(iPS.getUntrackedParameter<bool>("dump",false)==true)
00254 {
00255 edm::MallocOpts mo = mopts.get();
00256 LogWarning("MemoryCheck")
00257 << "Malloc options: " << mo << "\n";
00258 }
00259 }
00260
00261 SimpleMemoryCheck::~SimpleMemoryCheck()
00262 {
00263 #ifdef LINUX
00264 close(fd_);
00265 #endif
00266 }
00267
00268 void SimpleMemoryCheck::postBeginJob()
00269 {
00270 }
00271
00272 void SimpleMemoryCheck::preSourceConstruction(const ModuleDescription& md)
00273 {
00274 updateAndPrint("pre-ctor", md.moduleLabel_, md.moduleName_);
00275 }
00276
00277
00278 void SimpleMemoryCheck::postSourceConstruction(const ModuleDescription& md)
00279 {
00280 updateAndPrint("ctor", md.moduleLabel_, md.moduleName_);
00281 }
00282
00283 void SimpleMemoryCheck::postSource()
00284 {
00285 updateAndPrint("module", "source", "source");
00286 }
00287
00288 void SimpleMemoryCheck::postModuleConstruction(const ModuleDescription& md)
00289 {
00290 updateAndPrint("ctor", md.moduleLabel_, md.moduleName_);
00291 }
00292
00293 void SimpleMemoryCheck::postModuleBeginJob(const ModuleDescription& md)
00294 {
00295 updateAndPrint("beginJob", md.moduleLabel_, md.moduleName_);
00296 }
00297
00298 void SimpleMemoryCheck::postEndJob()
00299 {
00300 edm::LogAbsolute("MemoryReport")
00301 << "MemoryReport> Peak virtual size " << eventT1_.vsize << " Mbytes"
00302 << "\n"
00303 << " Key events increasing vsize: \n"
00304 << eventL2_ << "\n"
00305 << eventL1_ << "\n"
00306 << eventM_ << "\n"
00307 << eventR1_ << "\n"
00308 << eventR2_ << "\n"
00309 << eventT3_ << "\n"
00310 << eventT2_ << "\n"
00311 << eventT1_ ;
00312
00313 if (moduleSummaryRequested) {
00314 edm::LogAbsolute mmr("ModuleMemoryReport");
00315
00316
00317 mmr << "ModuleMemoryReport> Each line has module label and: \n";
00318 mmr << " (after early ignored events) \n";
00319 mmr <<
00320 " count of times module executed; average increase in vsize \n";
00321 mmr <<
00322 " maximum increase in vsize; event on which maximum occured \n";
00323 mmr << " (during early ignored events) \n";
00324 mmr << " total and maximum vsize increases \n \n";
00325 for (SignificantModulesMap::iterator im=modules_.begin();
00326 im != modules_.end(); ++im) {
00327 SignificantModule const& m = im->second;
00328 if ( m.totalDeltaVsize == 0 && m.totalEarlyVsize == 0 ) continue;
00329 mmr << im->first << ": ";
00330 mmr << "n = " << m.postEarlyCount;
00331 if ( m.postEarlyCount > 0 ) mmr << " avg = "
00332 << m.totalDeltaVsize/m.postEarlyCount;
00333 mmr << " max = " << m.maxDeltaVsize << " " << m.eventMaxDeltaV;
00334 if ( m.totalEarlyVsize > 0 ) {
00335 mmr << " early total: " << m.totalEarlyVsize;
00336 mmr << " max: " << m.maxEarlyVsize;
00337 }
00338 mmr << "\n";
00339 }
00340 }
00341
00342 Service<JobReport> reportSvc;
00343
00344 #define SIMPLE_MEMORY_CHECK_ORIGINAL_XML_OUTPUT
00345 #ifdef SIMPLE_MEMORY_CHECK_ORIGINAL_XML_OUTPUT
00346 std::map<std::string, double> reportData;
00347
00348 if (eventL2_.vsize > 0)
00349 eventStatOutput("LargeVsizeIncreaseEventL2", eventL2_, reportData);
00350 if (eventL1_.vsize > 0)
00351 eventStatOutput("LargeVsizeIncreaseEventL1", eventL1_, reportData);
00352 if (eventM_.vsize > 0)
00353 eventStatOutput("LargestVsizeIncreaseEvent", eventM_, reportData);
00354 if (eventR1_.vsize > 0)
00355 eventStatOutput("LargeVsizeIncreaseEventR1", eventR1_, reportData);
00356 if (eventR2_.vsize > 0)
00357 eventStatOutput("LargeVsizeIncreaseEventR2", eventR2_, reportData);
00358 if (eventT3_.vsize > 0)
00359 eventStatOutput("ThirdLargestVsizeEventT3", eventT3_, reportData);
00360 if (eventT3_.vsize > 0)
00361 eventStatOutput("SecondLargestVsizeEventT2", eventT2_, reportData);
00362 if (eventT3_.vsize > 0)
00363 eventStatOutput("LargestVsizeEventT1", eventT1_, reportData);
00364
00365 struct mallinfo minfo = mallinfo();
00366 reportData.insert(
00367 std::make_pair("HEAP_ARENA_SIZE_BYTES", minfo.arena));
00368 reportData.insert(
00369 std::make_pair("HEAP_ARENA_N_UNUSED_CHUNKS", minfo.ordblks));
00370 reportData.insert(
00371 std::make_pair("HEAP_TOP_FREE_BYTES", minfo.keepcost));
00372 reportData.insert(
00373 std::make_pair("HEAP_MAPPED_SIZE_BYTES", minfo.hblkhd));
00374 reportData.insert(
00375 std::make_pair("HEAP_MAPPED_N_CHUNKS", minfo.hblks));
00376 reportData.insert(
00377 std::make_pair("HEAP_USED_BYTES", minfo.uordblks));
00378 reportData.insert(
00379 std::make_pair("HEAP_UNUSED_BYTES", minfo.fordblks));
00380
00381 if (moduleSummaryRequested) {
00382 for (SignificantModulesMap::iterator im=modules_.begin();
00383 im != modules_.end(); ++im) {
00384 SignificantModule const& m = im->second;
00385 if ( m.totalDeltaVsize == 0 && m.totalEarlyVsize == 0 ) continue;
00386 std::string label = im->first+":";
00387 reportData.insert(
00388 std::make_pair(label+"PostEarlyCount", m.postEarlyCount));
00389 if ( m.postEarlyCount > 0 ) {
00390 reportData.insert(
00391 std::make_pair(label+"AverageDeltaVsize",
00392 m.totalDeltaVsize/m.postEarlyCount));
00393 }
00394 reportData.insert(
00395 std::make_pair(label+"MaxDeltaVsize",m.maxDeltaVsize));
00396 if ( m.totalEarlyVsize > 0 ) {
00397 reportData.insert(
00398 std::make_pair(label+"TotalEarlyVsize", m.totalEarlyVsize));
00399 reportData.insert(
00400 std::make_pair(label+"MaxEarlyDeltaVsize", m.maxEarlyVsize));
00401 }
00402 }
00403 }
00404
00405 reportSvc->reportMemoryInfo(reportData);
00406 #endif
00407
00408 #ifdef SIMPLE_MEMORY_CHECK_DIFFERENT_XML_OUTPUT
00409 std::vector<std::string> reportData;
00410
00411 if (eventL2_.vsize > 0) reportData.push_back(
00412 eventStatOutput("LargeVsizeIncreaseEventL2", eventL2_));
00413 if (eventL1_.vsize > 0) reportData.push_back(
00414 eventStatOutput("LargeVsizeIncreaseEventL1", eventL1_));
00415 if (eventM_.vsize > 0) reportData.push_back(
00416 eventStatOutput("LargestVsizeIncreaseEvent", eventM_));
00417 if (eventR1_.vsize > 0) reportData.push_back(
00418 eventStatOutput("LargeVsizeIncreaseEventR1", eventR1_));
00419 if (eventR2_.vsize > 0) reportData.push_back(
00420 eventStatOutput("LargeVsizeIncreaseEventR2", eventR2_));
00421 if (eventT3_.vsize > 0) reportData.push_back(
00422 eventStatOutput("ThirdLargestVsizeEventT3", eventT3_));
00423 if (eventT3_.vsize > 0) reportData.push_back(
00424 eventStatOutput("SecondLargestVsizeEventT2", eventT2_));
00425 if (eventT3_.vsize > 0) reportData.push_back(
00426 eventStatOutput("LargestVsizeEventT1", eventT1_));
00427
00428 struct mallinfo minfo = mallinfo();
00429 reportData.push_back(
00430 mallOutput("HEAP_ARENA_SIZE_BYTES", minfo.arena));
00431 reportData.push_back(
00432 mallOutput("HEAP_ARENA_N_UNUSED_CHUNKS", minfo.ordblks));
00433 reportData.push_back(
00434 mallOutput("HEAP_TOP_FREE_BYTES", minfo.keepcost));
00435 reportData.push_back(
00436 mallOutput("HEAP_MAPPED_SIZE_BYTES", minfo.hblkhd));
00437 reportData.push_back(
00438 mallOutput("HEAP_MAPPED_N_CHUNKS", minfo.hblks));
00439 reportData.push_back(
00440 mallOutput("HEAP_USED_BYTES", minfo.uordblks));
00441 reportData.push_back(
00442 mallOutput("HEAP_UNUSED_BYTES", minfo.fordblks));
00443
00444 reportSvc->reportMemoryInfo(reportData);
00445
00446 #endif
00447 }
00448
00449 void SimpleMemoryCheck::preEventProcessing(const edm::EventID& iID,
00450 const edm::Timestamp& iTime)
00451 {
00452 currentEventID_ = iID;
00453 }
00454
00455 void SimpleMemoryCheck::postEventProcessing(const Event& e,
00456 const EventSetup&)
00457 {
00458 ++count_;
00459 update();
00460 updateEventStats( e.id() );
00461 if (oncePerEventMode) {
00462
00463 updateMax();
00464 andPrint("event", "", "");
00465 }
00466 }
00467
00468 void SimpleMemoryCheck::preModule(const ModuleDescription& md) {
00469 update();
00470 moduleEntryVsize_ = current_->vsize;
00471 }
00472
00473 void SimpleMemoryCheck::postModule(const ModuleDescription& md) {
00474 if (!oncePerEventMode) {
00475 updateAndPrint("module", md.moduleLabel_, md.moduleName_);
00476 } else if (moduleSummaryRequested) {
00477 update();
00478 }
00479 if (moduleSummaryRequested) {
00480 double dv = current_->vsize - moduleEntryVsize_;
00481 std::string label = md.moduleLabel_;
00482 updateModuleMemoryStats (modules_[label],dv);
00483 }
00484 }
00485
00486
00487 void SimpleMemoryCheck::update()
00488 {
00489 std::swap(current_,previous_);
00490 *current_ = fetch();
00491 }
00492
00493 void SimpleMemoryCheck::updateMax()
00494 {
00495 if ((*current_ > max_) || oncePerEventMode)
00496 {
00497 if(count_ >= num_to_skip_) {
00498 }
00499 max_ = *current_;
00500 }
00501 }
00502
00503 void SimpleMemoryCheck::updateEventStats(edm::EventID const & e) {
00504 if (count_ < num_to_skip_) return;
00505 if (count_ == num_to_skip_) {
00506 eventT1_.set(0, 0, e, this);
00507 eventM_.set (0, 0, e, this);
00508 return;
00509 }
00510 double vsize = current_->vsize;
00511 double deltaVsize = vsize - eventT1_.vsize;
00512 if (vsize > eventT1_.vsize) {
00513 double deltaRss = current_->rss - eventT1_.rss;
00514 eventT3_ = eventT2_;
00515 eventT2_ = eventT1_;
00516 eventT1_.set(deltaVsize, deltaRss, e, this);
00517 }
00518 if (deltaVsize > eventM_.deltaVsize) {
00519 double deltaRss = current_->rss - eventM_.rss;
00520 if (eventL1_.deltaVsize >= eventR1_.deltaVsize) {
00521 eventL2_ = eventL1_;
00522 } else {
00523 eventL2_ = eventR1_;
00524 }
00525 eventL1_ = eventM_;
00526 eventM_.set(deltaVsize, deltaRss, e, this);
00527 eventR1_ = SignificantEvent();
00528 eventR2_ = SignificantEvent();
00529 } else if (deltaVsize > eventR1_.deltaVsize) {
00530 double deltaRss = current_->rss - eventM_.rss;
00531 eventR2_ = eventR1_;
00532 eventR1_.set(deltaVsize, deltaRss, e, this);
00533 } else if (deltaVsize > eventR2_.deltaVsize) {
00534 double deltaRss = current_->rss - eventR1_.rss;
00535 eventR2_.set(deltaVsize, deltaRss, e, this);
00536 }
00537 }
00538
00539 void SimpleMemoryCheck::andPrint(const std::string& type,
00540 const std::string& mdlabel, const std::string& mdname) const
00541 {
00542 if ((*current_ > max_) || oncePerEventMode)
00543 {
00544 if(count_ >= num_to_skip_) {
00545 double deltaVSIZE = current_->vsize - max_.vsize;
00546 double deltaRSS = current_->rss - max_.rss;
00547 if (!showMallocInfo) {
00548 LogWarning("MemoryCheck")
00549 << "MemoryCheck: " << type << " "
00550 << mdname << ":" << mdlabel
00551 << " VSIZE " << current_->vsize << " " << deltaVSIZE
00552 << " RSS " << current_->rss << " " << deltaRSS
00553 << "\n";
00554 } else {
00555 struct mallinfo minfo = mallinfo();
00556 LogWarning("MemoryCheck")
00557 << "MemoryCheck: " << type << " "
00558 << mdname << ":" << mdlabel
00559 << " VSIZE " << current_->vsize << " " << deltaVSIZE
00560 << " RSS " << current_->rss << " " << deltaRSS
00561 << " HEAP-ARENA [ SIZE-BYTES " << minfo.arena
00562 << " N-UNUSED-CHUNKS " << minfo.ordblks
00563 << " TOP-FREE-BYTES " << minfo.keepcost << " ]"
00564 << " HEAP-MAPPED [ SIZE-BYTES " << minfo.hblkhd
00565 << " N-CHUNKS " << minfo.hblks << " ]"
00566 << " HEAP-USED-BYTES " << minfo.uordblks
00567 << " HEAP-UNUSED-BYTES " << minfo.fordblks
00568 << "\n";
00569 }
00570 }
00571 }
00572 }
00573
00574 void SimpleMemoryCheck::updateAndPrint(const std::string& type,
00575 const std::string& mdlabel, const std::string& mdname)
00576 {
00577 update();
00578 andPrint(type, mdlabel, mdname);
00579 updateMax();
00580 }
00581
00582 #ifdef SIMPLE_MEMORY_CHECK_ORIGINAL_XML_OUTPUT
00583 void
00584 SimpleMemoryCheck::eventStatOutput(std::string title,
00585 SignificantEvent const& e,
00586 std::map<std::string, double> &m) const
00587 {
00588 { std::ostringstream os;
00589 os << title << "-a-COUNT";
00590 m.insert(std::make_pair(os.str(), e.count)); }
00591 { std::ostringstream os;
00592 os << title << "-b-RUN";
00593 m.insert(std::make_pair(os.str(), static_cast<double>
00594 (e.event.run()) )); }
00595 { std::ostringstream os;
00596 os << title << "-c-EVENT";
00597 m.insert(std::make_pair(os.str(), static_cast<double>
00598 (e.event.event()) )); }
00599 { std::ostringstream os;
00600 os << title << "-d-VSIZE";
00601 m.insert(std::make_pair(os.str(), e.vsize)); }
00602 { std::ostringstream os;
00603 os << title << "-e-DELTV";
00604 m.insert(std::make_pair(os.str(), e.deltaVsize)); }
00605 { std::ostringstream os;
00606 os << title << "-f-RSS";
00607 m.insert(std::make_pair(os.str(), e.rss)); }
00608 }
00609 #endif
00610
00611
00612 #ifdef SIMPLE_MEMORY_CHECK_DIFFERENT_XML_OUTPUT
00613 std::string
00614 SimpleMemoryCheck::eventStatOutput(std::string title,
00615 SignificantEvent const& e) const
00616 {
00617 std::ostringstream os;
00618 os << " <" << title << ">\n";
00619 os << " " << e.count << ": " << e.event;
00620 os << " vsize " << e.vsize-e.deltaVsize << " + " << e.deltaVsize
00621 << " = " << e.vsize;
00622 os << " rss: " << e.rss << "\n";
00623 os << " </" << title << ">\n";
00624 return os.str();
00625 }
00626
00627 std::string
00628 SimpleMemoryCheck::mallOutput(std::string title, size_t const& n) const {
00629 std::ostringstream os;
00630 os << " <" << title << ">\n";
00631 os << " " << n << "\n";
00632 os << " </" << title << ">\n";
00633 return os.str();
00634 }
00635 #endif
00636
00637 void
00638 SimpleMemoryCheck::updateModuleMemoryStats(SignificantModule & m,
00639 double dv) {
00640 if(count_ < num_to_skip_) {
00641 m.totalEarlyVsize += dv;
00642 if (dv > m.maxEarlyVsize) m.maxEarlyVsize = dv;
00643 } else {
00644 ++m.postEarlyCount;
00645 m.totalDeltaVsize += dv;
00646 if (dv > m.maxDeltaVsize) {
00647 m.maxDeltaVsize = dv;
00648 m.eventMaxDeltaV = currentEventID_;
00649 }
00650 }
00651 }
00652
00653
00654
00655 std::ostream &
00656 operator<< (std::ostream & os,
00657 SimpleMemoryCheck::SignificantEvent const & se) {
00658 os << "[" << se.count << "] "
00659 << se.event << " vsize = " << se.vsize
00660 << " deltaVsize = " << se.deltaVsize
00661 << " rss = " << se.rss << " delta " << se.deltaRss;
00662 return os;
00663 }
00664
00665 std::ostream &
00666 operator<< (std::ostream & os,
00667 SimpleMemoryCheck::SignificantModule const & sm) {
00668 if ( sm.postEarlyCount > 0 ) {
00669 os << "\nPost Early Events: TotalDeltaVsize: " << sm.totalDeltaVsize
00670 << " (avg: " << sm.totalDeltaVsize/sm.postEarlyCount
00671 << "; max: " << sm.maxDeltaVsize
00672 << " during " << sm.eventMaxDeltaV << ")";
00673 }
00674 if ( sm.totalEarlyVsize > 0 ) {
00675 os << "\n Early Events: TotalDeltaVsize: " << sm.totalEarlyVsize
00676 << " (max: " << sm.maxEarlyVsize << ")";
00677 }
00678
00679 return os;
00680 }
00681
00682
00683
00684
00685 }
00686 }
00687