当前位置: 首页 > news >正文

深圳 网站开发公司热点事件舆情分析

深圳 网站开发公司,热点事件舆情分析,软件开发工程师做什么,WordPress章节插件文章目录 线程monitor的流程怎么判断线程是否泄漏AddThreadJoinThreadExitThreadDetachThread 总结 前面我们通过研究KOOM的开源代码#xff0c;研究了关于Java层和native层内存泄漏监控的实现原理。还剩下线程泄漏这部分没有进行分析#xff0c;今天来补全它。整体下来… 文章目录 线程monitor的流程怎么判断线程是否泄漏AddThreadJoinThreadExitThreadDetachThread 总结 前面我们通过研究KOOM的开源代码研究了关于Java层和native层内存泄漏监控的实现原理。还剩下线程泄漏这部分没有进行分析今天来补全它。整体下来相信我们对于内存监控在代码上的实现上会有一个较为体系化的了解。 线程monitor的流程 从开启monitor的startLoop方法开始 override fun call(): LoopState {handleThreadLeak()return LoopState.Continue }一路进入方法栈到了这里 void Refresh() {auto info new SimpleHookInfo(Util::CurrentTimeNs());sHookLooper-post(ACTION_REFRESH, info); }看下sHookLooper类 namespace koom { class HookLooper : public looper {public:koom::ThreadHolder *holder;HookLooper();~HookLooper();void handle(int what, void *data);void post(int what, void *data); };根据ACTION_REFRESH来看看有哪些action enum HookAction {ACTION_ADD_THREAD,ACTION_START_THREAD,ACTION_JOIN_THREAD,ACTION_EXIT_THREAD,ACTION_DETACH_THREAD,ACTION_INIT,ACTION_REFRESH,ACTION_SET_NAME, };根据action的处理找到了handler处理message的地方 namespace koom { const char *looper_tag koom-hook-looper; HookLooper::HookLooper() : looper() { this-holder new koom::ThreadHolder(); } HookLooper::~HookLooper() { delete this-holder; } void HookLooper::handle(int what, void *data) {looper::handle(what, data);switch (what) {case ACTION_ADD_THREAD: {koom::Log::info(looper_tag, AddThread);auto info static_castHookAddInfo *(data);holder-AddThread(info-tid, info-pthread, info-is_thread_detached,info-time, info-create_arg);delete info;break;}case ACTION_JOIN_THREAD: {koom::Log::info(looper_tag, JoinThread);auto info static_castHookInfo *(data);holder-JoinThread(info-thread_id);delete info;break;}case ACTION_DETACH_THREAD: {koom::Log::info(looper_tag, DetachThread);auto info static_castHookInfo *(data);holder-DetachThread(info-thread_id);delete info;break;}case ACTION_EXIT_THREAD: {koom::Log::info(looper_tag, ExitThread);auto info static_castHookExitInfo *(data);holder-ExitThread(info-thread_id, info-threadName, info-time);delete info;break;}case ACTION_REFRESH: {koom::Log::info(looper_tag, Refresh);auto info static_castSimpleHookInfo *(data);holder-ReportThreadLeak(info-time);delete info;break;}default: {}} } void HookLooper::post(int what, void *data) { looper::post(what, data); } } // namespace koom可以发现不同线程相关的操作都进行了处理。 以HookThreadStart为例看看发送这个message的地方 ALWAYS_INLINE void ThreadHooker::HookThreadStart(void *arg) {koom::Log::info(thread_tag, HookThreadStart);auto *hookArg (StartRtnArg *)arg;pthread_attr_t attr;pthread_t self pthread_self();int state 0;if (pthread_getattr_np(self, attr) 0) {pthread_attr_getdetachstate(attr, state);}int tid (int)syscall(SYS_gettid);koom::Log::info(thread_tag, HookThreadStart %p, %d, %d, self, tid,hookArg-thread_create_arg-stack_time);auto info new HookAddInfo(tid, Util::CurrentTimeNs(), self,state PTHREAD_CREATE_DETACHED,hookArg-thread_create_arg);sHookLooper-post(ACTION_ADD_THREAD, info);void *(*start_rtn)(void *) hookArg-start_rtn;void *routine_arg hookArg-arg;delete hookArg;start_rtn(routine_arg); }这个方法被HookThreadCreate方法调用 int ThreadHooker::HookThreadCreate(pthread_t *tidp, const pthread_attr_t *attr,void *(*start_rtn)(void *), void *arg) {if (hookEnabled() start_rtn ! nullptr) {auto time Util::CurrentTimeNs();koom::Log::info(thread_tag, HookThreadCreate);auto *hook_arg new StartRtnArg(arg, Util::CurrentTimeNs(), start_rtn);auto *thread_create_arg hook_arg-thread_create_arg;void *thread koom::CallStack::GetCurrentThread();if (thread ! nullptr) {koom::CallStack::JavaStackTrace(thread,hook_arg-thread_create_arg-java_stack);}koom::CallStack::FastUnwind(thread_create_arg-pc,koom::Constant::kMaxCallStackDepth);thread_create_arg-stack_time Util::CurrentTimeNs() - time;return pthread_create(tidp, attr,reinterpret_castvoid *(*)(void *)(HookThreadStart),reinterpret_castvoid *(hook_arg));}return pthread_create(tidp, attr, start_rtn, arg); }HookThreadCreate又被RegisterSo调用。 bool ThreadHooker::RegisterSo(const std::string lib, int source) {if (IsLibIgnored(lib)) {return false;}auto lib_ctr lib.c_str();koom::Log::info(thread_tag, HookSo %d %s, source, lib_ctr);xhook_register(lib_ctr, pthread_create,reinterpret_castvoid *(HookThreadCreate), nullptr);xhook_register(lib_ctr, pthread_detach,reinterpret_castvoid *(HookThreadDetach), nullptr);xhook_register(lib_ctr, pthread_join,reinterpret_castvoid *(HookThreadJoin), nullptr);xhook_register(lib_ctr, pthread_exit,reinterpret_castvoid *(HookThreadExit), nullptr);return true; }来到这里hook实现的地方找到了还是通过爱奇艺的xhook把线程操作的系统API给hook出来了。 到这里整体的实现思路出来了通过looper不断轮询获取handler定时发送的message去refresh一些进程里面各个线程相关信息。 而线程信息则是通过native hook技术中中PLT hook来实现hook和信息获取。 上述分析知道了整体实现hook的流程但是拿到系统API之后做了什么。下面继续分析 怎么判断线程是否泄漏 AddThread void ThreadHolder::AddThread(int tid, pthread_t threadId, bool isThreadDetached,int64_t start_time, ThreadCreateArg *create_arg) {bool valid threadMap.count(threadId) 0;if (valid) return;koom::Log::info(holder_tag, AddThread tid:%d pthread_t:%p, tid, threadId);auto item threadMap[threadId];item.Clear();item.thread_internal_id threadId;item.thread_detached isThreadDetached;item.startTime start_time;item.create_time create_arg-time;item.id tid;std::string stack item.create_call_stack;stack.assign();try {// native stackint ignoreLines 0;for (int index 0; index koom::Constant::kMaxCallStackDepth; index) {uintptr_t p create_arg-pc[index];if (p 0) continue;// koom::Log::info(holder_tag, unwind native callstack #%d pc%p, index,// p);std::string line koom::CallStack::SymbolizePc(p, index - ignoreLines);if (line.empty()) {ignoreLines;} else {line.append(\n);stack.append(line);}}// java stackstd::vectorstd::string splits koom::Util::Split(create_arg-java_stack.str(), \n);for (const auto split : splits) {if (split.empty()) continue;std::string line;line.append(#);line.append(split);line.append(\n);stack.append(line);}//空白堆栈去掉##if (stack.size() 3) stack.assign();} catch (const std::bad_alloc ) {stack.assign(error:bad_alloc);}delete create_arg;koom::Log::info(holder_tag, AddThread finish); }这里拿到了线程创建时间和id等信息。 JoinThread void ThreadHolder::JoinThread(pthread_t threadId) {bool valid threadMap.count(threadId) 0;koom::Log::info(holder_tag, JoinThread tid:%p, threadId);if (valid) {threadMap[threadId].thread_detached true;} else {leakThreadMap.erase(threadId);} }ExitThread void ThreadHolder::ExitThread(pthread_t threadId, std::string threadName,long long int time) {bool valid threadMap.count(threadId) 0;if (!valid) return;auto item threadMap[threadId];koom::Log::info(holder_tag, ExitThread tid:%p name:%s, threadId,item.name.c_str());item.exitTime time;item.name.assign(threadName);if (!item.thread_detached) {// 泄露了koom::Log::error(holder_tag,Exited thread Leak! Not joined or detached!\n tid:%p,threadId);leakThreadMap[threadId] item;}threadMap.erase(threadId);koom::Log::info(holder_tag, ExitThread finish); }DetachThread void ThreadHolder::DetachThread(pthread_t threadId) {bool valid threadMap.count(threadId) 0;koom::Log::info(holder_tag, DetachThread tid:%p, threadId);if (valid) {threadMap[threadId].thread_detached true;} else {leakThreadMap.erase(threadId);} }可以发现代码是通过thread_detached这个参数来判断线程是否泄漏了假如进程执行了ExitThread但是thread_detached还没有解除则判断为线程泄漏。 接着就是收集一些线程的信息存储到容器里面。 这些为后续做堆栈回溯信息和整体信息的记录做了一些准备。 总结 通过通篇下来关于线程泄漏监控相关的思路我们是有了但是具体细节其实还有很多。 篇幅和时间原因这篇就介绍到这里。
http://www.hkea.cn/news/14562262/

相关文章:

  • 北京网站设计联系电话淘宝网网页版登录入口在哪里
  • 多语言外贸企业网站源码免费好用的crm系统
  • 网站建设经验典型做期货要关注哪些网站
  • 八卦岭网站建设百度电脑版官网下载
  • 深圳国内网站设计公司仿银行网站 asp
  • 淘宝网站开发实训报告2023网站推荐
  • 做网站为什么赚钱小学校园网站建设方案工作职责
  • ppt模板免费下载网站哪个好个人成立咨询公司的条件
  • vs网站制作教程开发一个打车软件需要多少钱
  • 大同网站建设优化推广四川今天刚刚发生的新闻
  • 张家界企业网站制作代理网络设置
  • 网站建设公司ipo网站优缺点分析
  • 关于建设招商网站的通知文化建设设计公司网站
  • seo网站建设刘贺稳营销专家a品牌商标设计logo
  • 黑龙江省建设网站首页wordpress打开网站加速
  • 青岛公司网站建设价格低四川省建设工程造价信息网站
  • 美食网站开发的难点免费ppt模板年终总结
  • php网站建设招聘一个主体可以备案几个网站
  • 网站内容好做住宿的有几个网站
  • 网站如何进行优化设计高职院校优质校建设专栏网站
  • 上海网站推广优化wordpress加载ajax
  • 安徽建筑工程网站麻六记网络营销方式
  • 城乡建设部官方网站网站名称大全
  • 安徽合肥网站制作北京住房与城乡建设厅网站首页
  • 免费加速器服务好的镇江网站优化
  • 线上购物网站开发外贸网站建设soho
  • 自己电脑做网站服务器广域网访问上海排名优化推广工具
  • wordpress 热门标签关键词优化搜索引擎
  • 郫县网站建设网站建设基本情况
  • 深圳企业建站高性价比的选择福田深圳网站建设