洋仔的博客 洋仔的博客
首页
  • 个人心法总结

    • 价值心法
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • iOS基础知识
  • 前端
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 投资体系
  • 毛选
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

洋仔

奋斗的小青年
首页
  • 个人心法总结

    • 价值心法
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • iOS基础知识
  • 前端
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 投资体系
  • 毛选
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 学习

    • 费曼学习法
    • 笔记方法
    • 提高学习效率的策略
    • 提高记忆的技巧
    • 自律小建议
    • 处理问题的思路
    • 年终总结
    • 浅识SDUI
    • 搜索引擎使用技巧
    • WebView内存使用情况
      • APP的内存占用情况是如何检测出来的
      • webview为何不能用app的
  • 面试

  • 心情杂货

  • 实用技巧

  • 投资体系

  • 毛选

  • 友情链接
  • 其他
  • 学习
洋仔
2023-11-12
目录

WebView内存使用情况

# APP的内存占用情况是如何检测出来的

# webview为何不能用app的

历史原因:

早期 UIWebView 由于与 app 共享内存空间, 会容易导致app/浏览器卡顿、白屏、甚至崩溃,甚至 input 传个大图/文件如果处理不当就直接崩;之后 WKWebView 虽然优化了 WebView 内存及管理,但仍存在很多bug,加上 iPhone 本身内存空间较小,综合起来还是容易出现卡顿、白屏、甚至崩溃问题;

WKWebview 会开辟进程(不是线程)来处理任务;

开辟的进程包括一个 content 的渲染进程和一个 networking 的网络处理进程; WKWebview 开辟的进程如果在内 存超过预算之后,使用 WKWebview 的当前 app 并不会被杀掉,最多就是 WKWebview 展示的页面变成空白页;

WKWebview 开启进程所占用的内存虽然不会影响当前 app,但是毕竟 iOS 中使用的是共享物理内存,当占用内存过大时,必定会影响到 app 的执行效率。如果 WKWebview 没有及时销毁,甚至会发生 CPU 抢占的现象,加剧原 APP 的效率问题;

但要注意,iOS 现在 App 基本会用 WKWebView,这种情况下客户端是拿不到页面(WebView)的内存信息的(因为系统共享 WebView 虚拟内存),因此像 DoraemonKit 的内存模块也是无法观察页面内存情况,这时候的方案就是获取整个设备的内存信息,通过观察设备内存变化来进行判断,缺点就是难以保证其他应用及系统的影响;

FBMemoryProfiler则可以检测所有类型的内存泄漏,原理是hook了系统的alloc和dealloc函数,跟instruments的功能类似,只不过更加轻量化,可以在APP运行时实时看到内存分配的情况,如果有对象内存泄漏,则会标红表示。

uint64_t FBMemoryProfilerResidentMemoryInBytes() { kern_return_t rval = 0; mach_port_t task = mach_task_self();

struct task_basic_info info = {0}; mach_msg_type_number_t tcnt = TASK_BASIC_INFO_COUNT; task_flavor_t flavor = TASK_BASIC_INFO;

task_info_t tptr = (task_info_t) &info;

if (tcnt > sizeof(info)) return 0;

rval = task_info(task, flavor, tptr, &tcnt); if (rval != KERN_SUCCESS) { return 0; }

return info.resident_size; }

DoraemonKit 可能使用了一些与 Instruments 类似的技术来监测应用的内存占用情况。一种常见的方法是使用 Objective-C 运行时(Objective-C Runtime)来动态地获取对象的信息,包括对象的内存占用情况。通过追踪对象的创建和释放,可以估算应用在运行时的内存占用。

  • (NSInteger)useMemoryForApp{ task_vm_info_data_t vmInfo; mach_msg_type_number_t count = TASK_VM_INFO_COUNT; kern_return_t kernelReturn = task_info(mach_task_self(), TASK_VM_INFO, (task_info_t) &vmInfo, &count); if(kernelReturn == KERN_SUCCESS) { int64_t memoryUsageInByte = (int64_t) vmInfo.phys_footprint; return (NSInteger)(memoryUsageInByte/1024/1024); } else { return -1; } }

YYAppPerformanceMonitor

YYMemoryUsage memory_usage() { // 由内核提供的关于该进程的内存信息,包括虚拟内存,常驻内存,物理内存,最大常驻内存等 struct mach_task_basic_info info; mach_msg_type_number_t count = sizeof(info) / sizeof(integer_t); if (task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&info, &count) == KERN_SUCCESS) {

    YYMemoryUsage usage;
    usage.has_usage = info.resident_size / MEMORY_SIZE_PER_MB;
    usage.total = [NSProcessInfo processInfo].physicalMemory / MEMORY_SIZE_PER_MB;
    usage.ratio = (double)info.resident_size / (double)[NSProcessInfo processInfo].physicalMemory * 100;
    return usage;
}
return (YYMemoryUsage){ 0 };

}

创建了一个定时器,每隔0.5s从内核中读取该进程的内存信息 从内核中读取该进程的内存信息 // 由内核提供的关于该进程的内存信息,包括虚拟内存,常驻内存,物理内存,最大常驻内存等

检测webvew的内存有两种

1.使用instrument检测webvew的内存 2.在webview中显示内存使用的情况

// YourViewController.h #import <UIKit/UIKit.h> #import <WebKit/WebKit.h>

@interface YourViewController : UIViewController

@property (nonatomic, strong) WKWebView *webView;

@end

// YourViewController.m #import "YourViewController.h"

@implementation YourViewController

  • (void)viewDidLoad { [super viewDidLoad];

    WKUserContentController *userContentController = [[WKUserContentController alloc] init]; [userContentController addScriptMessageHandler:self name:@"memoryUsage"];

    WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init]; configuration.userContentController = userContentController;

    self.webView = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:configuration]; [self.view addSubview:self.webView];

    NSString *htmlString = @"

    "; [self.webView loadHTMLString:htmlString baseURL:nil]; }

  • (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message { if ([message.name isEqualToString:@"memoryUsage"]) { NSDictionary *memoryInfo = message.body; // 处理从 JavaScript 传递过来的内存信息 NSLog(@"Total Memory: %@, Used Memory: %@", memoryInfo[@"totalMemory"], memoryInfo[@"usedMemory"]); } }

@end

编辑 (opens new window)
上次更新: 2024/10/23, 23:26:17
搜索引擎使用技巧
面试问题集锦

← 搜索引擎使用技巧 面试问题集锦→

最近更新
01
数组
10-25
02
数组双指针系列之对撞指针
10-25
03
数组双指针系列之快慢指针
10-25
更多文章>
Theme by Vdoing | Copyright © 2019-2024 Evan Xu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式