Giter VIP home page Giter VIP logo

oomdetector's Introduction

简介

OOMDetector是一个iOS内存监控组件,应用此组件可以帮助你轻松实现OOM监控、大内存分配监控、内存泄漏检测等功能。

特性

  • 1.OOM监控:监控OOM,Dump引起爆内存的堆栈
  • 2.大内存分配监控:监控单次大块内存分配,提供分配堆栈信息
  • 3.内存泄漏检测:可检测OC对象、Malloc堆内存泄漏,提供泄漏堆栈信息

演示

demo_gif

支持CocoaPods

在Podfile中添加如下文本

  pod 'OOMDetector', '1.3'

然后在命令行中运行

  pod install

需要注意的是OOMDetector使用了fishhook (0.2) 如果你的工程中也使用了fishhook,建议移除,并统一使用CocoaPods管理

  pod 'fishhook', '0.2'

堆栈翻译

  translate_oom.py dsym_file oom_file

dsym_file app的符号表路径,如OOMDetector.app.dSYM

oom_file Library/OOMDetector路径下的爆内存日志,如normal_malloc20180125_211259558.log

使用方法

初始化

// 初始化,6s以下机型内存触顶阈值默认设置为300M,6s及以上机型内存触顶阈值默认设置为800M。

- (void)setupWithDefaultConfig;

OOM监控

// 开启OOM监控,默认在setupWithDefaultConfig方法中已经开启

-(void)startMaxMemoryStatistic:(double)overFlowLimit;

大内存分配监控

// 开启单次大内存分配监控

-(BOOL)startSingleChunkMallocDetector:(size_t)threshholdInBytes callback:(ChunkMallocBlock)callback;

内存泄漏检测

// 初始化内存泄漏监控器,记录所有堆对象

- (void)setupLeakChecker;

// 执行一次泄露检测,建议在主线程调用,该操作会挂起所有子线程进行泄露检测(该操作较耗时,平均耗时在1s以上,请限制调用频率)

-(void)executeLeakCheck:(QQLeakCheckCallback)callback;

其它功能

// 开启堆内存堆栈监控,开启后会实时记录所有的内存分配堆栈,并将多次重复调用的相同堆栈合并,如果合并后的size大于threshHoldInbytes,该分配堆栈将被输出到log用于分析,log路径Library/OOMDetector

-(BOOL)startMallocStackMonitor:(size_t)threshholdInBytes needAutoDumpWhenOverflow:(BOOL)needAutoDump dumpLimit:(double)dumpLimit sampleInterval:(NSTimeInterval)sampleInterval;

// 开启VMStackMonitor用以监控非直接通过malloc方式分配的内存因为startVMStackMonitor:方法用到了私有API __syscall_logger会带来app store审核不通过的风险,此方法默认只在DEBUG模式下生效,如果需要在RELEASE模式下也可用,请打开USE_VM_LOGGER_FORCEDLY宏,但是切记在提交appstore前将此宏关闭,否则可能会审核不通过

-(BOOL)startVMStackMonitor:(size_t)threshHoldInbytes;

设置代理

@protocol QQOOMPerformanceDataDelegate // 在调用startMaxMemoryStatistic:开启内存触顶监控后会触发此回调,返回前一次app运行时单次生命周期内的最大物理内存数据

-(void)performanceData:(NSDictionary *)data completionHandler:(void (^)(BOOL))completionHandler; @end

@protocol QQOOMFileDataDelegate // 在出现单次大块内存分配、检查到内存泄漏且时、调用uploadAllStack方法时触发此回调

-(void)fileData:(NSData *)data extra:(NSDictionary<NSString *,NSString *> *)extra type:(QQStackReportType)type completionHandler:(void (^)(BOOL))completionHandler; @end

PS

如果你遇到类似"Undefined symbols for architecture arm64: "std::__1::__next_prime(unsigned long)""的链接问题, 你可以做如下设置:

Build Settings -> Linking -> Other Linker Flags -> -lc++

变更记录

暂无

帮助

暂无

许可证

OOMDetector适用MIT协议,详见LICENSE


Introduction

OOMDetector is a memory monitoring component for iOS which provides you with OOM monitoring, memory allocation monitoring, memory leak detection and other functions.

Features

  • OOM Monitoring : Monitoring OOM then dump stacks which cause OOM problems.
  • Large Memory Allocation Monitoring : Monitoring large memory allocation then provides memory allocation stacks for you.
  • Memory Leak Detecting : Detecting memory leak for both OC objects and c heap memory then provides memory allocation stacks for you.

Demo

demo_gif

Usage

Initialization

// 初始化,6s以下机型内存触顶阈值默认设置为300M,6s及以上机型内存触顶阈值默认设置为800M。

- (void)setupWithDefaultConfig;

OOM Monitoring

// 开启OOM监控,默认在setupWithDefaultConfig方法中已经开启

-(void)startMaxMemoryStatistic:(double)overFlowLimit;

Large Memory Allocation Monitoring

// 开启单次大内存分配监控

-(BOOL)startSingleChunkMallocDetector:(size_t)threshholdInBytes callback:(ChunkMallocBlock)callback;

Memory Leak Detecting

// 初始化内存泄漏监控器,记录所有堆对象

- (void)setupLeakChecker;

// 执行一次泄露检测,建议在主线程调用,该操作会挂起所有子线程进行泄露检测(该操作较耗时,平均耗时在1s以上,请限制调用频率)

-(void)executeLeakCheck:(QQLeakCheckCallback)callback;

Other Functions

// 开启堆内存堆栈监控,开启后会实时记录所有的内存分配堆栈,并将多次重复调用的相同堆栈合并,如果合并后的size大于threshHoldInbytes,该分配堆栈将被输出到log用于分析,log路径Library/OOMDetector

-(BOOL)startMallocStackMonitor:(size_t)threshholdInBytes needAutoDumpWhenOverflow:(BOOL)needAutoDump dumpLimit:(double)dumpLimit sampleInterval:(NSTimeInterval)sampleInterval;

// 开启VMStackMonitor用以监控非直接通过malloc方式分配的内存因为startVMStackMonitor:方法用到了私有API __syscall_logger会带来app store审核不通过的风险,此方法默认只在DEBUG模式下生效,如果需要在RELEASE模式下也可用,请打开USE_VM_LOGGER_FORCEDLY宏,但是切记在提交appstore前将此宏关闭,否则可能会审核不通过

-(BOOL)startVMStackMonitor:(size_t)threshHoldInbytes;

Delegate

@protocol QQOOMPerformanceDataDelegate // 在调用startMaxMemoryStatistic:开启内存触顶监控后会触发此回调,返回前一次app运行时单次生命周期内的最大物理内存数据

-(void)performanceData:(NSDictionary *)data completionHandler:(void (^)(BOOL))completionHandler; @end

@protocol QQOOMFileDataDelegate // 在出现单次大块内存分配、检查到内存泄漏且时、调用uploadAllStack方法时触发此回调

-(void)fileData:(NSData *)data extra:(NSDictionary<NSString *,NSString *> *)extra type:(QQStackReportType)type completionHandler:(void (^)(BOOL))completionHandler; @end

PS

If you come across link errors like "Undefined symbols for architecture arm64: "std::__1::__next_prime(unsigned long)"", do as follows:

Build Settings -> Linking -> Other Linker Flags -> -lc++

Known Issues

Conflict with fishhook

现在已知Podfile中有FBRetainCycleDetector时会有编译错误,原因是FBRetainCycleDetector中包含了fishhook,目前遇到这种情况,请先移除FBRetainCycleDetector,然后再pod install试试

Changes Log

Help

License

OOMDetector is under the MIT license. See the LICENSE file for details.

oomdetector's People

Contributors

adonisyuan avatar gsdios avatar rosen0510 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

oomdetector's Issues

demo crash

image

可以看下这里闪退是什么原因么 第一个demo点击运行demo 然后check内存泄漏 实在不知道怎么改 哭唧唧

关于OOMDetector更新的几点建议

因为看到有这个不错的工具,因此在研究集成到工程中去,特意花了几天把源代码研读一番,下面是个人给出的几个建议希望能尽快升级这个库:

1.bool CStackHelper::isInAppAddress(vm_address_t addr)这个函数的实现不完全正确,第0个image的内容不一定就是可执行程序本身,有可能是dyld库或者其他一些比如用于XCODE调试和分析的一些支持库。

2.对于程序中获取所有image信息的数据结构AppImages看到只在一处进行初始化构建,但是实际中某些image是可能在运行时动态加载和卸载的,因此需要有一个机制能够在运行时动态更新所有的image信息。还是bool CStackHelper::getImageByAddr(vm_address_t addr,segImageInfo *image)这个函数有可能会返回false然后我看代码里面有不少这个函数的使用,当返回false时不进行处理,这样就如我上面说的某一些在运行时加载的image就无法查找到对应的信息从而漏了记录。

3.建议对获取的image信息进行开始地址和结束地址排序排列,这样在进行一些地址归属某个image时比如:bool CStackHelper::getImageByAddr(vm_address_t addr,segImageInfo *image)函数就可以用二分查找法来增强性能。

4.在编程风格上看到有OC代码有C++代码,但是代码中貌似没有语言层面分层的概念,有时候在众多C++代码中又突然调用OC代码,然后OC代码中又突然调用C++代码。这样的设计方法我觉得有待优化。

5.最后,优秀的开源库还是值得去接入和使用的。

关于私有api使用线上问题

大佬们请教下,腾讯内部是做的混淆获取的虚拟内存,还是使用的其他技术手段,比如hook虚拟内存的分配函数? 但经过实践,hook方案不好使,有没有可以指点的?

调用 executeLeakCheck:(QQLeakCheckCallback)callback app 崩溃

调用 executeLeakCheck:(QQLeakCheckCallback)callback 导致 app 崩溃.

size_t CStacksHashmap::hash_code(void *key) { uint64_t *value_1 = (uint64_t *)key; uint64_t *value_2 = value_1 + 1; size_t offset = (size_t)(*value_1 + *value_2)%(entry_num - 1); return offset; }

crash 在 size_t offset = (size_t)(*value_1 + *value_2)%(entry_num - 1);

求问😓 堆栈翻译:translate_oom.py dsym_file oom_file

终端打印如下日志:
Begin Translation......
APP Name:OOMDetector
begin translate stack:...
pre_begin:63 begin:99

pre_begin:63 begin:99

atos success!
stack_cnt:1
end translate stack:...
end Translation......
看了下脚本,是不是翻译完后的脚本后缀是translated.log;
但是我这边没有生成,请问是什么原因。

根据文档的说明,沙盒中没找到.log的文件

沙盒中没找到.log的文件,在/Library/Foom/目录下,有.oom的文件,爆内存的堆栈信息是记录在这个文件内的吗?如果是的话,按照文档的说明,使用translate_oom.py解析该.oom文件,得到的.log文件是空,size为0

image

对于iOS混合Unity的工程会报错

Player data archive not found at /var/containers/Bundle/Application/CF09F982-D893-49E1-AA92-64D6D04370C3/ProductName.app/Data/data.unity3d, using local filesystem
2018-01-26 10:50:10.843760+0800 ProductName[1573:287190] Metal GPU Frame Capture Enabled
2018-01-26 10:50:10.844361+0800 ProductName[1573:287190] Metal API Validation Disabled
2018-01-26 10:50:11.224427+0800 ProductName[1573:287190] [MC] Lazy loading NSBundle MobileCoreServices.framework
2018-01-26 10:50:11.226120+0800 ProductName[1573:287190] [MC] Loaded MobileCoreServices.framework
2018-01-26 10:50:11.233780+0800 ProductName[1573:287190] [MC] System group container for systemgroup.com.apple.configurationprofiles path is /private/var/containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles
warning: could not execute support code to read Objective-C class data in the process. This may reduce the quality of type information available.

jietu20180126-105415

野指针crash

调用get_all_leak_ptrs方法中的代码:

qleak_ptrs_hashmap->removePtr(current->address,NULL,NULL);

removePtr中释放了current所指向的内存,但是外面的current指针并没有置NULL,导致野指针crash

怎样动态的开启和停止

有个场景是:需要的时候开启 不需要的时候停止监控。 现在拷贝了demo的startOOMDetector方法开启了监控 在需要停止监控的时候该怎样做 目前我调用了stopVMStackMonitor, stopMallocStackMonitor ,stopSingleChunkMallocDetector, currentLeakChecker] stopStackLogging,好像不起作用

malloc: Attempted to register zone more than once

初始化的代码:
OOMDetector *detector = [OOMDetector getInstance];
[detector setupWithDefaultConfig];
检测内存代码:
[[OOMDetector getInstance] executeLeakCheck:^(NSString *leakStack, size_t total_num){
self.textView.text = leakStack;
}];
第一次调用检测代码能够检测出内存泄漏
default
第二次再调用
2019-01-03 10 04 41
这里报 malloc: Attempted to register zone more than once: 0x16fd65bd8

app使用内存计算的与xcode计算的不一致

  • (double)appUsedMemory中计算出的app内存使用值与xcode中Memory Report的值相差很多,试了下通过phys_footprint来计算与xcode的基本一致,能告诉你们这样计算的原因吗

会发生死锁,it may lead to dead lock

此组件在一些情况下会发生死锁,不知道项目大神们有没有什么建议
未能稳定复现此问题,故不知道原因在哪

This project will lead to deadlock under certain circumstances. Still trying to find what happened.

无法打包发布

ITMS-90338: Non-public API usage - The app references non-public symbols in Frameworks/OOMDetector.framework/OOMDetector: ___syscall_logger. If method names in your source code match the private Apple APIs listed above, altering your method names will help prevent this app from being flagged in future submissions. In addition, note that one or more of the above APIs may be located in a static library that was included with your app. If so, they must be removed. For further information, visit the Technical Support Information at http://developer.apple.com/support/technical/

为什么无法检测到OC对象的内存泄漏?

我写了一个ViewController测试以下几种方式引发的内存漏泄,但是发现日志并没有检测结果,这是什么原因?

这个ViewController 是这样写的:

@interface TableView : NSObject
@property(nonatomic) Byte *space;
@property(nonatomic, copy) void (^block)();
-(void)sayHello;
@end

#define kTenMB  1048576 * 10
@implementation TableView
- (instancetype)init {
    self = [super init];
    if (self) {
        //分配 10MB 内存
        self.space = malloc(kTenMB);
        memset(self.space, 0, kTenMB);
    }
    return self;
}
-(void)sayHello {
    NSLog(@"Hello!");
}
- (void)dealloc {
    NSLog(@"=== %s",__func__);
    free(self.space);
}
@end


@interface AViewController ()
@property(nonatomic, copy) void (^block)();
@property(nonatomic, strong) TableView *tableView;

@end

@implementation AViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.title = @"A";
    self.view.backgroundColor = UIColor.greenColor;
    
// ---- Block ,self leak ----
   self.block = ^{
//        [self test];
       NSLog(@"== title:%@",self.title);
   };
   self.block();

   // ---- tableView leak ----
   TableView *tableView = [TableView new];
   tableView.block = ^{
       [tableView sayHello];
   };
    
}

- (void)dealloc {
    NSLog(@"==== %s %@",__func__,self);

}

@end

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 也做了以下配置:

[[OOMDetector getInstance] setupWithDefaultConfig];
// 开启内存泄漏监控
[[OOMDetector getInstance] setupLeakChecker];

Is there a recommended setting?

-(BOOL)startMallocStackMonitor:(size_t)threshholdInBytes needAutoDumpWhenOverflow:(BOOL)needAutoDump dumpLimit:(double)dumpLimit sampleInterval:(NSTimeInterval)sampleInterval;

关于内存泄漏检测的疑问

阅读源码后有个疑惑的地方,望解惑。

假如我在主线程调用执行进行无主内存检测,此时有子线程调用malloc分配内存,并还未执行到free函数,刚好该线程被挂起,无法执行free。那么是否会认为这个地方产生了无主内存块?

谢谢!

UnsafeMutalbePointer.allocate泄漏没有检查到

@IBAction func makeLeaks(_ sender: Any) { let size = 51 * 1024 * 1024 let payload = UnsafeMutablePointer<UInt8>.allocate(capacity: size) let data = Data() data.copyBytes(to: payload, count: size) }
这份代码应该是会创建泄漏的内存的,但是用executeLeakCheck没有检测到

oom_file 为何为全 0 文件

在启用监控后,运行程序一段时间,显示 App 内存从 80M 暴增至 300M,随查看生成的名为的 normal_malloc20180621_093431650.logoom_file 文件,结果显示该文件为 16 进制全 0 文件,字节数为 524KB,且多次此时该文件均为 524KB。

摘录如下

0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000

请问这种现象正常么,如何解决呢

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.