Skip to content

Commit

Permalink
1.use use_unfair_lock to optimize performance
Browse files Browse the repository at this point in the history
2.separate QQLeak and OOMDetector
3.use mmap to dump OOM Data
4.add FOOMMonitor to monitor SIGKILL
5.use CRC64 to compress stack data
6.add sample factor to sampling small memory stacks
  • Loading branch information
rosenluo committed Jun 18, 2019
1 parent d6d1e39 commit 271fdf5
Show file tree
Hide file tree
Showing 51 changed files with 2,567 additions and 1,507 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
## Build generated
build/
DerivedData/
*.DS_Store

## Various settings
*.pbxuser
Expand Down
36 changes: 25 additions & 11 deletions Demo/OOMDetector.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
objects = {

/* Begin PBXBuildFile section */
4AE2C5E220883ACC0042D00B /* libOOMDetector.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4AE2C5E120883ACC0042D00B /* libOOMDetector.framework */; };
6B12C6421F9621F9000B42F0 /* DemoListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B12C6411F9621F9000B42F0 /* DemoListViewController.m */; };
6B12C6461F962E14000B42F0 /* DemoViewController0.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B12C6451F962E14000B42F0 /* DemoViewController0.m */; };
6B12C6491F962EA9000B42F0 /* DemoViewController1.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B12C6481F962EA9000B42F0 /* DemoViewController1.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
Expand All @@ -16,12 +17,14 @@
6B9A04F51FD5823800414B1F /* BaseDemoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B8C22E71F8E494C007DE399 /* BaseDemoViewController.m */; };
6B9A04F61FD5823800414B1F /* DemoViewController2.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B12C7011F974AB8000B42F0 /* DemoViewController2.m */; };
6B9A04F71FD5823800414B1F /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B8C22E41F8E494C007DE399 /* AppDelegate.m */; };
6BADA10D1FA8AC0F00668479 /* DemoViewController3.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BADA10C1FA8AC0F00668479 /* DemoViewController3.m */; };
6BADA10D1FA8AC0F00668479 /* DemoViewController3.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BADA10C1FA8AC0F00668479 /* DemoViewController3.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; };
6BF6879C1FC3C4D500054160 /* MyOOMDataManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 6BF6879B1FC3C4D500054160 /* MyOOMDataManager.m */; };
7DE3285020107E9B007A188B /* libOOMDetector.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7DE3285120107E9B007A188B /* libOOMDetector.framework */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
4A9C1E3A208499EC00E54134 /* libOOMDetector_QQ.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = libOOMDetector_QQ.framework; sourceTree = BUILT_PRODUCTS_DIR; };
4A9C1E3C20849A7800E54134 /* libOOMDetector.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = libOOMDetector.framework; sourceTree = BUILT_PRODUCTS_DIR; };
4AE2C5E120883ACC0042D00B /* libOOMDetector.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = libOOMDetector.framework; sourceTree = BUILT_PRODUCTS_DIR; };
6B12C6401F9621F9000B42F0 /* DemoListViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DemoListViewController.h; sourceTree = "<group>"; };
6B12C6411F9621F9000B42F0 /* DemoListViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DemoListViewController.m; sourceTree = "<group>"; };
6B12C6441F962E14000B42F0 /* DemoViewController0.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DemoViewController0.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -51,7 +54,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
7DE3285020107E9B007A188B /* libOOMDetector.framework in Frameworks */,
4AE2C5E220883ACC0042D00B /* libOOMDetector.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -113,6 +116,9 @@
6B9A04F21FD5816F00414B1F /* Frameworks */ = {
isa = PBXGroup;
children = (
4AE2C5E120883ACC0042D00B /* libOOMDetector.framework */,
4A9C1E3C20849A7800E54134 /* libOOMDetector.framework */,
4A9C1E3A208499EC00E54134 /* libOOMDetector_QQ.framework */,
7DE3285120107E9B007A188B /* libOOMDetector.framework */,
);
name = Frameworks;
Expand Down Expand Up @@ -329,19 +335,23 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = 8D5EHT9KTL;
DEVELOPMENT_TEAM = JVT843N4EQ;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
Build_For_Extern,
);
INFOPLIST_FILE = OOMDetectorDemo/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
NEW_SETTING = "";
ONLY_ACTIVE_ARCH = NO;
OTHER_LDFLAGS = "-lc++";
PRODUCT_BUNDLE_IDENTIFIER = com.tencentgsd.OOMDemo;
OTHER_LDFLAGS = (
"-lc++",
"-force_load",
"$(BUILT_PRODUCTS_DIR)/libOOMDetector.framework/libOOMDetector",
);
PRODUCT_BUNDLE_IDENTIFIER = com.tencent.rosen;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand All @@ -357,14 +367,18 @@
CLANG_ENABLE_OBJC_ARC = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 8D5EHT9KTL;
DEVELOPMENT_TEAM = JVT843N4EQ;
GCC_PREPROCESSOR_DEFINITIONS = Build_For_Extern;
INFOPLIST_FILE = OOMDetectorDemo/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
NEW_SETTING = "";
OTHER_LDFLAGS = "-lc++";
PRODUCT_BUNDLE_IDENTIFIER = com.tencentgsd.OOMDemo;
OTHER_LDFLAGS = (
"-lc++",
"-force_load",
"$(BUILT_PRODUCTS_DIR)/libOOMDetector.framework/libOOMDetector",
);
PRODUCT_BUNDLE_IDENTIFIER = com.tencent.rosen;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
TARGETED_DEVICE_FAMILY = "1,2";
Expand Down

This file was deleted.

116 changes: 99 additions & 17 deletions Demo/OOMDetectorDemo/AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,23 @@
#import "AppDelegate.h"
#import "MyOOMDataManager.h"
#import "DemoListViewController.h"
#import <objc/runtime.h>
#import <sys/mman.h>
#import <mach/mach.h>
#import <libOOMDetector/FOOMMonitor.h>

#define USE_VM_LOGGER

#ifdef USE_VM_LOGGER
typedef void (malloc_logger_t)(uint32_t type, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t result, uint32_t num_hot_frames_to_skip);

extern malloc_logger_t* __syscall_logger;
#endif

static void oom_log_callback(char *info)
{
NSLog(@"%s",info);
}

@import libOOMDetector;

Expand All @@ -31,13 +48,49 @@ @interface AppDelegate ()
@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

[self setupWindow];
[[OOMDetector getInstance] registerLogCallback:oom_log_callback];
[self setupFOOMMonitor];
[self setupOOMDetector];

return YES;
}

- (void)applicationWillTerminate:(UIApplication *)application
{
[[FOOMMonitor getInstance] appWillTerminate];
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
[[FOOMMonitor getInstance] appDidEnterBackground];
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
[[FOOMMonitor getInstance] appWillEnterForground];
}

- (void)applicationDidCrashed
{
//crash 捕获组件的回调
[[FOOMMonitor getInstance] appDidCrashed];
}

- (void)applicationDetectedDeadlock
{
//检测到死锁,可以使用blue组件捕获
//[[QQBlueFrameMonitor getInstance] startDeadLockMonitor:^(double cost, NSArray *stacks) {
// [[FOOMMonitor getInstance] appDetectDeadLock:stacks];
//}];
[[FOOMMonitor getInstance] appDetectDeadLock:nil];
}

- (void)applicationResumeFromDeadlock
{
//从死锁恢复
[[FOOMMonitor getInstance] appResumeFromDeadLock];
}

- (void)setupWindow
{
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
Expand All @@ -46,6 +99,13 @@ - (void)setupWindow
[self.window makeKeyAndVisible];
}

- (void)setupFOOMMonitor
{
[[FOOMMonitor getInstance] setAppVersion:@"OOMDetector_demo"];
//设置爆内存监控,爆内存监控用于监控App前台爆内存和卡死,这个可以全量开启
[[FOOMMonitor getInstance] start];
}

- (void)setupOOMDetector
{
OOMDetector *detector = [OOMDetector getInstance];
Expand All @@ -56,31 +116,53 @@ - (void)setupOOMDetector

// 设置捕获堆栈数据、内存log代理,在出现单次大块内存分配、检查到内存泄漏且时、调用uploadAllStack方法时会触发此回调
[detector setFileDataDelegate:[MyOOMDataManager getInstance]];
// 设置app内存触顶监控数据代理,在调用startMaxMemoryStatistic:开启内存触顶监控后会触发此回调,返回前一次app运行时单次生命周期内的最大物理内存数据
//
// // 设置app内存触顶监控数据代理,在调用startMaxMemoryStatistic:开启内存触顶监控后会触发此回调,返回前一次app运行时单次生命周期内的最大物理内存数据
[detector setPerformanceDataDelegate:[MyOOMDataManager getInstance]];
// 单次大块内存分配监控
//
// // 单次大块内存分配监控
[detector startSingleChunkMallocDetector:50 * 1024 * 1024 callback:^(size_t bytes, NSString *stack) {
[[NSNotificationCenter defaultCenter] postNotificationName:kChunkMallocNoti object:stack];
}];

// 开启内存泄漏监控,目前只可检测真机运行时的内存泄漏,模拟器暂不支持
// 开启内存泄漏监控,目前只可检测真机运行时的内存泄漏,模拟器暂不支持,这个功能占用的内存较大,建议只在测试阶段使用
[detector setupLeakChecker];

// 开启MallocStackMonitor用以监控通过malloc方式分配的内存
[detector startMallocStackMonitor:10 * 1024 * 1024 needAutoDumpWhenOverflow:YES dumpLimit:300 sampleInterval:0.1];

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

// 调用该接口上报所有缓存的OOM相关log给通过setFileDataDelegate:方法设置的代理,建议在启动的时候调用
[detector uploadAllStack];
// 开启MallocStackMonitor用以监控通过malloc方式分配的内存,会增加8%左右的cpu开销和10Mb内存,所以建议抽样开启
[detector startMallocStackMonitor:30 * 1024 * 1024 logUUID:[[FOOMMonitor getInstance] getLogUUID]];
//30K以下堆栈按10%抽样监控
// OOMDetector *oomdetector = [OOMDetector getInstance];
// [oomdetector setMallocSampleFactor:10];
// [oomdetector setMallocNoSampleThreshold:30*1024];
// // 开启VMStackMonitor用以监控非直接通过malloc方式分配的内存
// // 因为startVMStackMonitor:方法用到了私有API __syscall_logger会带来app store审核不通过的风险,此方法默认只在DEBUG模式下生效,如果
// // 需要在RELEASE模式下也可用,请打开USE_VM_LOGGER_FORCEDLY宏,但是切记在提交appstore前将此宏关闭,否则可能会审核不通过
// [detector setVMLogger:(void**)&__syscall_logger];
// [detector startVMStackMonitor:30 * 1024 * 1024 logUUID:[[FOOMMonitor getInstance] getLogUUID]];

/*************************************************************************/

}

-(void)testmmap
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *LibDirectory = [paths objectAtIndex:0];
NSString *path = [LibDirectory stringByAppendingPathComponent:@"test.log"];
FILE *fp = fopen ( [path fileSystemRepresentation] , "wb+" ) ;
char *ptr = (char *)mmap(0, 50*1024*1024, PROT_WRITE | PROT_READ, (MAP_FILE|MAP_SHARED), fileno(fp), 0);
munmap(ptr,50*1024*1024);
}

-(void)performanceData:(NSDictionary *)data completionHandler:(void (^)(BOOL))completionHandler
{
//上报
}

/** 在出现单次大块内存分配、检查到内存泄漏且时、调用uploadAllStack方法时触发回调 */
-(void)fileData:(id)data extra:(NSDictionary<NSString*,NSString*> *)extra type:(QQStackReportType)type completionHandler:(void (^)(BOOL))completionHandler
{
//上报
}

@end
9 changes: 8 additions & 1 deletion Demo/OOMDetectorDemo/Demos/DemoViewController0.m
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,14 @@ - (void)checkLeak

- (void)runDemoCode
{
Demo0Code
for(int i = 0; i < 600000; i++){
char *test1 = malloc(1024);
memset(test1, 0, 1024);
if(i % 2 == 0){
free(test1);
}
}
// Demo0Code
}

- (NSString *)demoCodeText
Expand Down
7 changes: 6 additions & 1 deletion Demo/OOMDetectorDemo/Demos/DemoViewController2.m
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,12 @@ - (void)onReceiveChunkMallocNoti:(NSNotification *)noti

- (void)runDemoCode
{
DemoCode2
int size = 51 * 1024 * 1024;
char *info = malloc(size);
memset(info, 1, size);
// dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{\
// free(info);
// });
}

- (NSString *)demoCodeText
Expand Down
31 changes: 5 additions & 26 deletions Demo/OOMDetectorDemo/Demos/DemoViewController3.m
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,6 @@
@import libOOMDetector;


#define DemoCode3 \
int i = 0;\
while (i < 3000) {\
[self.arr addObject:[[NSObject alloc] init]];\
++i;\
}\

@interface DemoViewController3 ()

@property (nonatomic, strong) NSTimer *timer;
@property (nonatomic, strong) NSMutableArray *arr;

@end

@implementation DemoViewController3

- (void)viewDidLoad
Expand All @@ -44,18 +30,11 @@ - (void)viewDidLoad

self.isOOMDemo = YES;
self.resultLabel.hidden = YES;
self.arr = [NSMutableArray new];
}

- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];

[self.timer invalidate];
self.timer = nil;

[self.arr removeAllObjects];
self.arr = nil;
}

- (NSString *)demoDescriptionString
Expand All @@ -65,15 +44,15 @@ - (NSString *)demoDescriptionString

- (void)runDemoCode
{
if (!self.timer) {
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(test) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
}
[self test];
}

- (void)test
{
DemoCode3
while (1) {
NSObject *obj = [[[NSObject alloc] init] retain];
[obj class];
}
}

- (NSString *)demoCodeText
Expand Down
8 changes: 6 additions & 2 deletions Demo/OOMDetectorDemo/MyOOMDataManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,13 @@ - (void)fileData:(NSData *)data extra:(NSDictionary<NSString *,NSString *> *)ext

if (type == QQStackReportTypeOOMLog) {
// 此处为了Demo演示需要传参数NO,NO表示我们自己业务对data处理尚未完成或者失败,OOMDetector内部暂时不会删除临时文件
completionHandler(NO);
if(completionHandler){
completionHandler(NO);
}
} else {
completionHandler(YES);
if(completionHandler){
completionHandler(YES);
}
}
}

Expand Down
Binary file not shown.
Loading

0 comments on commit 271fdf5

Please sign in to comment.