AutorÃa | Ultima modificación | Ver Log |
// Copyright 2020 Google LLC//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at//// http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.#import "FirebasePerformance/Sources/Gauges/Memory/FPRMemoryGaugeCollector.h"#import "FirebasePerformance/Sources/Gauges/Memory/FPRMemoryGaugeCollector+Private.h"#import "FirebasePerformance/Sources/AppActivity/FPRSessionManager.h"#import "FirebasePerformance/Sources/Configurations/FPRConfigurations.h"#import "FirebasePerformance/Sources/FPRConsoleLogger.h"#include <malloc/malloc.h>@interface FPRMemoryGaugeCollector ()/** @brief Timer property used for the frequency of CPU data collection. */@property(nonatomic) dispatch_source_t timerSource;/** @brief Gauge collector queue on which the gauge data collected. */@property(nonatomic) dispatch_queue_t gaugeCollectorQueue;/** @brief Boolean to see if the timer is active or paused. */@property(nonatomic) BOOL timerPaused;@endFPRMemoryGaugeData *fprCollectMemoryMetric() {NSDate *collectionTime = [NSDate date];struct mstats ms = mstats();FPRMemoryGaugeData *gaugeData = [[FPRMemoryGaugeData alloc] initWithCollectionTime:collectionTimeheapUsed:ms.bytes_usedheapAvailable:ms.bytes_free];return gaugeData;}@implementation FPRMemoryGaugeCollector- (instancetype)initWithDelegate:(id<FPRMemoryGaugeCollectorDelegate>)delegate {self = [super init];if (self) {_delegate = delegate;_gaugeCollectorQueue =dispatch_queue_create("com.google.firebase.FPRMemoryGaugeCollector", DISPATCH_QUEUE_SERIAL);_configurations = [FPRConfigurations sharedInstance];_timerPaused = YES;[self updateSamplingFrequencyForApplicationState:[FPRAppActivityTracker sharedInstance].applicationState];}return self;}- (void)stopCollecting {if (self.timerPaused == NO) {dispatch_source_cancel(self.timerSource);self.timerPaused = YES;}}- (void)resumeCollecting {[self updateSamplingFrequencyForApplicationState:[FPRAppActivityTracker sharedInstance].applicationState];}- (void)updateSamplingFrequencyForApplicationState:(FPRApplicationState)applicationState {uint32_t frequencyInMs = (applicationState == FPRApplicationStateBackground)? [self.configurations memorySamplingFrequencyInBackgroundInMS]: [self.configurations memorySamplingFrequencyInForegroundInMS];[self captureMemoryGaugeAtFrequency:frequencyInMs];}#pragma mark - Internal methods./*** Captures the memory gauge at a defined frequency.** @param frequencyInMs Frequency at which the memory gauges are collected.*/- (void)captureMemoryGaugeAtFrequency:(uint32_t)frequencyInMs {[self stopCollecting];if (frequencyInMs > 0) {self.timerSource =dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self.gaugeCollectorQueue);dispatch_source_set_timer(self.timerSource,dispatch_time(DISPATCH_TIME_NOW, frequencyInMs * NSEC_PER_MSEC),frequencyInMs * NSEC_PER_MSEC, (1ull * NSEC_PER_SEC) / 10);FPRMemoryGaugeCollector __weak *weakSelf = self;dispatch_source_set_event_handler(weakSelf.timerSource, ^{FPRMemoryGaugeCollector *strongSelf = weakSelf;if (strongSelf) {[strongSelf collectMetric];}});dispatch_resume(self.timerSource);self.timerPaused = NO;} else {FPRLogDebug(kFPRMemoryCollection, @"Memory metric collection is disabled.");}}- (void)collectMetric {FPRMemoryGaugeData *gaugeMetric = fprCollectMemoryMetric();[self.delegate memoryGaugeCollector:self gaugeData:gaugeMetric];}@end