From b2ca610182eccff91f2cb1a77ed07aab88346116 Mon Sep 17 00:00:00 2001 From: shuaijie Date: Mon, 31 Jul 2023 11:43:11 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E7=B3=BB=E7=BB=9F=E7=9B=91=E8=A7=86?= =?UTF-8?q?=E5=99=A8=E5=8D=A0=E7=94=A8=E8=B5=84=E6=BA=90=E8=BF=87=E9=AB=98?= =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 系统监视器占用资源过高优化 Log: 系统监视器占用资源过高优化 --- .../compact_memory_monitor.cpp | 2 +- deepin-system-monitor-main/cpu_monitor.cpp | 2 +- .../gui/animation_stackedwidget.cpp | 2 +- .../gui/animation_stackedwidget.h | 2 +- deepin-system-monitor-main/memory_monitor.cpp | 2 +- .../process/process.cpp | 101 +++++++++++++++++- deepin-system-monitor-main/process/process.h | 2 + .../process/process_set.cpp | 80 +++++++++++--- .../process/process_set.h | 6 ++ .../system/sys_info.cpp | 18 ++-- deepin-system-monitor-main/system/sys_info.h | 1 + .../system/system_monitor.cpp | 16 ++- .../process/process.cpp | 10 ++ .../process/process.h | 2 + 14 files changed, 214 insertions(+), 32 deletions(-) diff --git a/deepin-system-monitor-main/compact_memory_monitor.cpp b/deepin-system-monitor-main/compact_memory_monitor.cpp index 6c362498..432c44e3 100644 --- a/deepin-system-monitor-main/compact_memory_monitor.cpp +++ b/deepin-system-monitor-main/compact_memory_monitor.cpp @@ -45,7 +45,7 @@ CompactMemoryMonitor::CompactMemoryMonitor(QWidget *parent) changeTheme(dAppHelper->themeType()); m_animation = new QPropertyAnimation(this, "progress", this); - m_animation->setDuration(250); + m_animation->setDuration(10); m_animation->setEasingCurve(QEasingCurve::OutQuad); m_animation->setStartValue(0); m_animation->setEndValue(1.0); diff --git a/deepin-system-monitor-main/cpu_monitor.cpp b/deepin-system-monitor-main/cpu_monitor.cpp index 25d6a100..caff43c7 100644 --- a/deepin-system-monitor-main/cpu_monitor.cpp +++ b/deepin-system-monitor-main/cpu_monitor.cpp @@ -50,7 +50,7 @@ CpuMonitor::CpuMonitor(QWidget *parent) connect(m_cpuInfomodel, &CPUInfoModel::modelUpdated, this, &CpuMonitor::updateStatus); m_animation = new QPropertyAnimation(this, "progress", this); - m_animation->setDuration(250); + m_animation->setDuration(20); m_animation->setStartValue(0.0); m_animation->setEndValue(1.0); m_animation->setEasingCurve(QEasingCurve::OutQuad); diff --git a/deepin-system-monitor-main/gui/animation_stackedwidget.cpp b/deepin-system-monitor-main/gui/animation_stackedwidget.cpp index af4d804c..acf1f609 100644 --- a/deepin-system-monitor-main/gui/animation_stackedwidget.cpp +++ b/deepin-system-monitor-main/gui/animation_stackedwidget.cpp @@ -11,7 +11,7 @@ AnimationStackedWidget::AnimationStackedWidget(const AnimationOri ori, QWidget * , m_animationOri(ori) , m_Animation(new QPropertyAnimation(this, "offset")) { - setDuration(250); + setDuration(20); connect(m_Animation , &QPropertyAnimation::finished , this diff --git a/deepin-system-monitor-main/gui/animation_stackedwidget.h b/deepin-system-monitor-main/gui/animation_stackedwidget.h index 0ecd8650..d0685836 100644 --- a/deepin-system-monitor-main/gui/animation_stackedwidget.h +++ b/deepin-system-monitor-main/gui/animation_stackedwidget.h @@ -23,7 +23,7 @@ class AnimationStackedWidget : public QStackedWidget * @brief setDuration 设置动画持续时间 * @param duration 动画时间 */ - void setDuration(int duration = 500); + void setDuration(int duration = 10); /** * @brief IsRunning 动画是否正在运行 * @return 动画师傅正在运行 diff --git a/deepin-system-monitor-main/memory_monitor.cpp b/deepin-system-monitor-main/memory_monitor.cpp index 2c58244c..5d41f802 100644 --- a/deepin-system-monitor-main/memory_monitor.cpp +++ b/deepin-system-monitor-main/memory_monitor.cpp @@ -47,7 +47,7 @@ MemoryMonitor::MemoryMonitor(QWidget *parent) m_animation = new QPropertyAnimation(this, "progress", this); m_animation->setStartValue(0.0); m_animation->setEndValue(1.0); - m_animation->setDuration(250); + m_animation->setDuration(10); connect(m_animation, &QPropertyAnimation::valueChanged, this, &MemoryMonitor::onValueChanged); connect(m_animation, &QPropertyAnimation::finished, this, &MemoryMonitor::onAnimationFinished); diff --git a/deepin-system-monitor-main/process/process.cpp b/deepin-system-monitor-main/process/process.cpp index da59b8ee..b3f5cdc6 100644 --- a/deepin-system-monitor-main/process/process.cpp +++ b/deepin-system-monitor-main/process/process.cpp @@ -119,6 +119,92 @@ timeval Process::procuptime() const return d->uptime; } +void Process::readProcessVariableInfo() +{ + d->valid = true; + + bool ok = true; + ok = ok && readStat(); +// readEnviron(); + readSchedStat(); + ok = ok && readStatm(); + + readIO(); + readSockInodes(); + + d->proc_name.refreashProcessName(this); + d->uptime = SysInfo::instance()->uptime(); + + CPUSet *cpuset = DeviceDB::instance()->cpuSet(); + ProcessSet *procset = ProcessDB::instance()->processSet(); + + auto recentProcptr = procset->getRecentProcStage(d->pid); + auto validrecentPtr = recentProcptr.lock(); + qreal timedelta = d->stime + d->utime; + if (validrecentPtr) { + timedelta = timedelta - validrecentPtr->ptime; + struct DiskIO io = {validrecentPtr->read_bytes, validrecentPtr->write_bytes, validrecentPtr->cancelled_write_bytes}; + d->diskIOSample->addSample(new DISKIOSampleFrame(validrecentPtr->uptime, io)); + + d->networkIOSample->addSample(new IOSampleFrame(validrecentPtr->uptime, {0, 0})); + } + d->cpuUsageSample->addSample(new CPUUsageSampleFrame(qMax(0., timedelta) / cpuset->getUsageTotalDelta() * 100)); + + struct DiskIO io = {d->read_bytes, d->write_bytes, d->cancelled_write_bytes}; + d->diskIOSample->addSample(new DISKIOSampleFrame(d->uptime, io)); + + auto pair = d->diskIOSample->recentSamplePair(); + struct IOPS iops = DISKIOSampleFrame::diskiops(pair.first, pair.second); + d->diskIOSpeedSample->addSample(new IOPSSampleFrame(iops)); + + qulonglong sum_recv = 0; + qulonglong sum_send = 0; + + for (int i = 0; i < d->sockInodes.size(); ++i) { + SockIOStat sockIOStat; + bool result = NetifMonitor::instance()->getSockIOStatByInode(d->sockInodes[i], sockIOStat); + if (result) { + sum_recv += sockIOStat->rx_bytes; + sum_send += sockIOStat->tx_bytes; + } + } + d->networkIOSample->addSample(new IOSampleFrame(d->uptime, {sum_recv, sum_send})); + + auto netpair = d->networkIOSample->recentSamplePair(); + struct IOPS netiops = IOSampleFrame::iops(netpair.first, netpair.second); + d->networkBandwidthSample->addSample(new IOPSSampleFrame(netiops)); + + d->valid = d->valid && ok; +} + +void Process::readProcessSimpleInfo() +{ + d->valid = true; + bool ok = true; +readEnviron(); + ok = ok && readStat(); + ok = ok && readStatus(); + ok = ok && readCmdline(); + + d->usrerName = SysInfo::userName(d->uid); + d->proc_name.refreashProcessName(this); + d->proc_icon.refreashProcessIcon(this); + + d->apptype = kNoFilter; + const QVariant &euid = ProcessDB::instance()->processEuid(); + WMWindowList *wmwindowList = ProcessDB::instance()->windowList(); + + if (euid == d->uid && (wmwindowList->isGuiApp(d->pid) + || wmwindowList->isTrayApp(d->pid) + || wmwindowList->isDesktopEntryApp(d->pid))) { + d->apptype = kFilterApps; + } else if (euid == d->uid) { + d->apptype = kFilterCurrentUser; + } + + d->valid = d->valid && ok; +} + void Process::readProcessInfo() { d->valid = true; @@ -207,6 +293,8 @@ bool Process::readStat() errno = 0; sprintf(path, PROC_STAT_PATH, d->pid); + if(access(path, R_OK) != 0) return !ok; /* no such dirent (anymore) */ + // open /proc/[pid]/stat if ((fd = open(path, O_RDONLY)) < 0) { print_errno(errno, QString("open %1 failed").arg(path)); @@ -281,6 +369,7 @@ bool Process::readCmdline() char *begin, *cur, *end; sprintf(path, PROC_CMDLINE_PATH, d->pid); + if(access(path, R_OK) != 0) return !ok; /* no such dirent (anymore) */ errno = 0; // open /proc/[pid]/cmdline @@ -328,6 +417,7 @@ void Process::readEnviron() int fd; sprintf(path, PROC_ENVIRON_PATH, d->pid); + if(access(path, R_OK) != 0) return; /* no such dirent (anymore) */ errno = 0; // open /proc/[pid]/environ @@ -372,6 +462,7 @@ void Process::readSchedStat() buf.reserve(bsiz); sprintf(path, PROC_SCHEDSTAT_PATH, d->pid); + if(access(path, R_OK) != 0) return; /* no such dirent (anymore) */ errno = 0; // open /proc/[pid]/schedstat @@ -405,6 +496,7 @@ bool Process::readStatus() buf.reserve(bsiz); sprintf(path, PROC_STATUS_PATH, d->pid); + if(access(path, R_OK) != 0) return !ok; /* no such dirent (anymore) */ errno = 0; uFile fp(fopen(path, "r")); @@ -453,6 +545,7 @@ bool Process::readStatm() ssize_t nr; sprintf(path, PROC_STATM_PATH, d->pid); + if(access(path, R_OK) != 0) return !ok; /* no such dirent (anymore) */ errno = 0; // open /proc/[pid]/statm @@ -492,6 +585,7 @@ void Process::readIO() char path[128], buf[bsiz]; sprintf(path, PROC_IO_PATH, d->pid); + if(access(path, R_OK) != 0) return; /* no such dirent (anymore) */ errno = 0; // open /proc/[pid]/io @@ -524,6 +618,7 @@ void Process::readSockInodes() struct stat sbuf; sprintf(path, PROC_FD_PATH, d->pid); + if(access(path, R_OK) != 0) return; /* no such dirent (anymore) */ errno = 0; // open /proc/[pid]/fd dir @@ -548,9 +643,9 @@ void Process::readSockInodes() } // ::if(stat) } // ::if(isdigit) } // ::while(readdir) - if (errno) { - print_errno(errno, QString("read %1 failed").arg(path)); - } + // if (errno) { + // print_errno(errno, QString("read %1 failed").arg(path)); + // } } bool Process::isValid() const diff --git a/deepin-system-monitor-main/process/process.h b/deepin-system-monitor-main/process/process.h index deeda39c..3e3643ba 100644 --- a/deepin-system-monitor-main/process/process.h +++ b/deepin-system-monitor-main/process/process.h @@ -115,6 +115,8 @@ class Process qulonglong sentBytes() const; void readProcessInfo(); + void readProcessSimpleInfo(); + void readProcessVariableInfo(); private: /** diff --git a/deepin-system-monitor-main/process/process_set.cpp b/deepin-system-monitor-main/process/process_set.cpp index e8f05bd3..78cefadb 100644 --- a/deepin-system-monitor-main/process/process_set.cpp +++ b/deepin-system-monitor-main/process/process_set.cpp @@ -7,6 +7,7 @@ #include "process/process_db.h" #include "common/common.h" #include "wm/wm_window_list.h" +#include "settings.h" #include @@ -25,6 +26,11 @@ ProcessSet::ProcessSet() , m_pidCtoPMapping {} , m_pidPtoCMapping {} { + m_prePid.clear(); + m_curPid.clear(); + m_pidMyApps.clear(); + m_simpleSet.clear(); + m_settings = Settings::instance(); } ProcessSet::ProcessSet(const ProcessSet &other) @@ -76,7 +82,7 @@ void ProcessSet::scanProcess() procstage->uptime = iter->procuptime(); m_recentProcStage[iter->pid()] = procstage; } - + m_curPid.clear(); m_set.clear(); m_pidPtoCMapping.clear(); m_pidCtoPMapping.clear(); @@ -86,15 +92,53 @@ void ProcessSet::scanProcess() QList appLst; while (iter.hasNext()) { Process proc = iter.next(); - if (!proc.isValid()) - continue; - m_set.insert(proc.pid(), proc); - m_pidPtoCMapping.insert(proc.ppid(), proc.pid()); - m_pidCtoPMapping.insert(proc.pid(), proc.ppid()); + if(!m_curPid.contains(proc.pid())) + m_curPid.append(proc.pid()); + + } + + if(m_prePid != m_curPid) { + for (const pid_t &pid : m_prePid) { + if(!m_curPid.contains(pid)){ + m_prePid.removeAt(pid); //remove disappear process pid + if(m_simpleSet.contains(pid)) + m_simpleSet.remove(pid); + if(m_pidMyApps.contains(pid)) + m_pidMyApps.removeAt(pid); + } + } + + for (const pid_t &pid : m_curPid) { + if(!m_prePid.contains(pid)){ //add new process pid + Process *proc = new Process(pid); + proc->readProcessSimpleInfo(); + if(!m_simpleSet.contains(pid)) + m_simpleSet.insert(proc->pid(), *proc); - if (proc.appType() == kFilterApps && !wmwindowList->isTrayApp(proc.pid())) { - appLst << proc.pid(); + if (proc->appType() == kFilterApps && !wmwindowList->isTrayApp(proc->pid())) { + m_pidMyApps << proc->pid(); + } + } + } + m_prePid = m_curPid; + } + + const QVariant &vindex = m_settings->getOption(kSettingKeyProcessTabIndex, kFilterApps); + int index = vindex.toInt(); + + for (const pid_t &pid : m_prePid) { + Process proc = m_simpleSet[pid]; + if( ((kFilterApps == index) && (proc.appType()<= kFilterApps)) || + ((kFilterCurrentUser == index) && (proc.appType() <= kFilterCurrentUser)) || + (kNoFilter == index)) { + proc.readProcessVariableInfo(); // + if (!proc.isValid()) + continue; + + m_set.insert(proc.pid(), proc); + m_pidPtoCMapping.insert(proc.ppid(), proc.pid()); + m_pidCtoPMapping.insert(proc.pid(), proc.ppid()); } } @@ -110,7 +154,7 @@ void ProcessSet::scanProcess() return b; }; - for (const pid_t &pid : appLst) { + for (const pid_t &pid : m_pidMyApps) { qreal recvBps = 0; qreal sendBps = 0; mergeSubProcNetIO(pid, recvBps, sendBps); @@ -120,7 +164,8 @@ void ProcessSet::scanProcess() mergeSubProcCpu(pid, ptotalCpu); m_set[pid].setCpu(ptotalCpu); - if (!wmwindowList->isGuiApp(pid)) { + if (!wmwindowList->isGuiApp(pid)) + { // only if no ancestor process is gui app we keep this process if (m_pidCtoPMapping.contains(pid) && anyRootIsGuiProc(m_pidCtoPMapping[pid])) { @@ -164,11 +209,9 @@ Process ProcessSet::Iterator::next() if (m_dirent && isdigit(m_dirent->d_name[0])) { auto pid = pid_t(atoi(m_dirent->d_name)); Process proc(pid); - proc.readProcessInfo(); advance(); - if (proc.isValid()) return proc; } @@ -179,7 +222,10 @@ void ProcessSet::Iterator::advance() { while ((m_dirent = readdir(m_dir.get()))) { if (isdigit(m_dirent->d_name[0])) - break; + if(pid_t(atoi(m_dirent->d_name)) < 10) + continue; + else + break; } if (!m_dirent && errno) { print_errno(errno, "read /proc failed"); @@ -198,6 +244,8 @@ const Process ProcessSet::getProcessById(pid_t pid) const QList ProcessSet::getPIDList() const { + const QVariant &vindex = m_settings->getOption(kSettingKeyProcessTabIndex, kFilterApps); + int index = vindex.toInt(); // 当系统读取到的m_set为空时,通过keys()函数返回会造成段错误 原因是keys函数效率低下,会造成大量的内存拷贝 // 替换方案是 QList pidList {}; @@ -206,7 +254,11 @@ QList ProcessSet::getPIDList() const QMap::key_iterator iterBegin = m_set.keyBegin(); for (;iterBegin != m_set.keyEnd(); ++iterBegin) { pid_t tmpKey = *iterBegin; - pidList.append(tmpKey); + Process proc = m_set[tmpKey]; + if( ((kFilterApps == index) && (proc.appType()<= kFilterApps)) || + ((kFilterCurrentUser == index) && (proc.appType() <= kFilterCurrentUser)) || + (kNoFilter == index)) + pidList.append(tmpKey); if (size != m_set.size()) break; } diff --git a/deepin-system-monitor-main/process/process_set.h b/deepin-system-monitor-main/process/process_set.h index b17160c4..3b9cf5b3 100644 --- a/deepin-system-monitor-main/process/process_set.h +++ b/deepin-system-monitor-main/process/process_set.h @@ -15,6 +15,7 @@ using namespace common::alloc; +class Settings; namespace core { namespace process { @@ -68,11 +69,16 @@ class ProcessSet }; private: + Settings *m_settings = nullptr; + QMap m_simpleSet; QMap m_set; QMap> m_recentProcStage {}; QMap m_pidCtoPMapping {}; // child to parent pid mapping QMultiMap m_pidPtoCMapping {}; // parent to child pid mapping + QList m_prePid; + QList m_curPid; + QList m_pidMyApps; friend class Iterator; }; diff --git a/deepin-system-monitor-main/system/sys_info.cpp b/deepin-system-monitor-main/system/sys_info.cpp index 9cd0c3e6..f4c19a69 100644 --- a/deepin-system-monitor-main/system/sys_info.cpp +++ b/deepin-system-monitor-main/system/sys_info.cpp @@ -208,6 +208,17 @@ bool SysInfo::readSockStat(SockStatMap &statMap) } void SysInfo::readSysInfo() +{ + d->nfds = read_file_nr(); + d->nprocs = read_processes(); + d->nthrs = read_threads(); + + read_uptime(d->uptime); + read_btime(d->btime); + read_loadavg(d->loadAvg); +} + +void SysInfo::readSysInfoStatic() { d->uid = getuid(); d->euid = geteuid(); @@ -223,16 +234,9 @@ void SysInfo::readSysInfo() d->effective_group_name = groupName(d->egid); if (d->effective_group_name.isEmpty()) d->effective_group_name = QByteArray(getenv("GROUP")); - - d->nfds = read_file_nr(); - d->nprocs = read_processes(); - d->nthrs = read_threads(); d->hostname = read_hostname(); d->arch = read_arch(); d->version = read_version(); - read_uptime(d->uptime); - read_btime(d->btime); - read_loadavg(d->loadAvg); } quint32 SysInfo::read_file_nr() diff --git a/deepin-system-monitor-main/system/sys_info.h b/deepin-system-monitor-main/system/sys_info.h index c1099081..7d59d51b 100644 --- a/deepin-system-monitor-main/system/sys_info.h +++ b/deepin-system-monitor-main/system/sys_info.h @@ -76,6 +76,7 @@ class SysInfo static QByteArray groupName(gid_t gid); void readSysInfo(); + void readSysInfoStatic(); static bool readSockStat(SockStatMap &statMap); private: diff --git a/deepin-system-monitor-main/system/system_monitor.cpp b/deepin-system-monitor-main/system/system_monitor.cpp index b7190e5d..1f0203fb 100644 --- a/deepin-system-monitor-main/system/system_monitor.cpp +++ b/deepin-system-monitor-main/system/system_monitor.cpp @@ -24,6 +24,7 @@ SystemMonitor::SystemMonitor(QObject *parent) , m_deviceDB(new DeviceDB()) , m_processDB(new ProcessDB(this)) { + m_sysInfo->readSysInfoStatic(); } @@ -69,15 +70,24 @@ void SystemMonitor::startMonitorJob() common::init::global_init(); m_basictimer.stop(); - m_basictimer.start(2000, Qt::VeryCoarseTimer, this); + m_basictimer.start(1000, Qt::VeryCoarseTimer, this); updateSystemMonitorInfo(); } - +static uint cnt = 0 ; void SystemMonitor::timerEvent(QTimerEvent *event) { + QObject::timerEvent(event); if (event->timerId() == m_basictimer.timerId()) { - updateSystemMonitorInfo(); + if(cnt & 0x0001){ + m_sysInfo->readSysInfo(); + m_deviceDB->update(); + m_processDB->update(); + } else { + emit statInfoUpdated(); + } + if(cnt++ >250) + cnt = 0; } } diff --git a/deepin-system-monitor-plugin-popup/process/process.cpp b/deepin-system-monitor-plugin-popup/process/process.cpp index a4577f57..faa20e98 100644 --- a/deepin-system-monitor-plugin-popup/process/process.cpp +++ b/deepin-system-monitor-plugin-popup/process/process.cpp @@ -119,6 +119,16 @@ timeval Process::procuptime() const return d->uptime; } +void Process::readProcessVariableInfo() +{ + readProcessInfo(); +} + +void Process::readProcessSimpleInfo() +{ + readProcessInfo(); +} + void Process::readProcessInfo() { d->valid = true; diff --git a/deepin-system-monitor-plugin-popup/process/process.h b/deepin-system-monitor-plugin-popup/process/process.h index deeda39c..7c159d83 100644 --- a/deepin-system-monitor-plugin-popup/process/process.h +++ b/deepin-system-monitor-plugin-popup/process/process.h @@ -115,6 +115,8 @@ class Process qulonglong sentBytes() const; void readProcessInfo(); + void readProcessVariableInfo(); + void readProcessSimpleInfo(); private: /**