I am running version 1.0.3 with React Native 58.6 (also tried 58.3).
I want to read several BLE characteristics each second.
When I read a characteristic each second, the memory usage of the app steadily increases in iOS. This is not happening in Android.
Please provide detailed steps for reproducing the issue.
I tested react-native-ble-plx v1.0.2 and react-native v58.3, it has the same issue. react-native-ble-plx v1.0.1 and react-native v57.5 does not seem to have the problem.
Hey,
I tested this issue with XCode 10.2.1, RN 0.58.5, and rn-ble-plx 1.0.3 and I couldn't reproduce your problems.
Please send me a results of your profiling via "Allocations" instruments.
Pretty sure it may be related to:
https://github.com/Polidea/RxBluetoothKit/issues/302
Hi,
We're in the process of upgrading our app that's been in production for about a year and a half. The app is written with react-native 47 and react-native-ble-plx 0.8.0 and we build it using Xcode 9.0. We've been working on upgrading the app to react-native 58.6 and react-native-ble-plx 1.0.3. During testing, we found that the upgraded app crashed on long running tests, when we looked into the reason for the crashes, it was insufficient memory.
When we profile our app, it appears that memory is constantly increasing regardless of user interaction. We are reading about eight characterics in an interval of 1 second. When our app is not connected to ble there is no issue with memory. All of these statistics were gathered from the app running with no user interaction, no network interaction, nothing other than BLE reads.
We wanted to rule out any other code in our app, and any other packages. So, we made a new, empty app with only react-native-ble-plx installed. We made one for both versions of react-native and react-native-ble-plx we have been testing. In these apps we are creating an interval and reading a single characteristic each second in the App.js component.
constructor() {
super()
console.log('app constructor xxx')
console.log('App didMount')
this.manager = new BleManager()
const subscription = this.manager.onStateChange((state) => {
if (state === 'PoweredOn') {
this.scanAndConnect()
subscription.remove()
}
}, true)
}
async scanAndConnect(byService = null) {
if (__DEV__) console.log('start scan')
this.manager.startDeviceScan(null, null, async (error, device) => {
console.log('Scanning...')
console.log(device.name)
if (device && device.name && (device.name.includes('name-of-device'))) {
if (__DEV__) console.log('BLE found. connecting.')
this.manager.stopDeviceScan()
if (__DEV__) console.log('stop scan, clear timers ')
device.connect()
.then(async (device) => {
if (__DEV__) console.log('Device = ' + device.id)
if (__DEV__) console.log('Discovering services and bleChars')
return (await device.discoverAllServicesAndCharacteristics())
})
.then((device) => {
console.log('Setting notifications')
setInterval(() => {
console.log('interval ')
device.readCharacteristicForService(serviceUUID, heartbeatUUID)
.then((res) => {
console.log(`heartbeat ${ res.value}`)
})
}, 1000)
})
}
})
}
"dependencies": {
"react": "16.0.0-alpha.12",
"react-native": "0.47.2",
"react-native-ble-plx": "github:Polidea/react-native-ble-plx#ac062c2ec7ad2da31d224a6c953178aa845f9537"
}
"dependencies": {
"react": "16.6.3",
"react-native": "0.58.6",
"react-native-ble-plx": "^1.0.3"
}
I've run all of these tests on an iPad 4 mini, but we've reproduced the same issues on an iPhone 6s.
Hello @andycamp
I see that your last post seems to have a mistake in titles before tests. E.g.
react-native 58.6, react-native-ble-plx 0.8.0, Xcode 10.2
"dependencies": { "react": "16.6.3", "react-native": "0.58.6", "react-native-ble-plx": "^1.0.3" }
You could fix them so we would be the accurate picture.
The best / most efficient way to track the leak would be if you could follow the steps suggested in the previous post
Best regards
Thanks. I fixed the mistake.
Are other titles ok?
Could you perform and report the suggested tests?
I did just find another mistake. I did perform the other tests, but I don't know of an easy way to share the results in this context, and it's unclear from the instructions exactly what I'm supposed to share. In a brand new app, with nothing running other than reading a characteristic each second, memory always increases. Stop reading the characteristic, and memory stays constant.
There should be an option to export the results. Even a screenshot of the list should be enough for a start
We're definitely still struggling with this. It doesn't make sense that RAM usage keeps going up. This running a react-native 58.6 app with react-native-ble-plx 1.0.3 using only the sample code that was posted last week.



I can't see any problems in your attached screen. I think that you should create minimal repository which reproduces issues on your side (could be a fork of SensorTag), so that we can test it.
Here's a repo that will reproduce the issues that we are seeing.
https://github.com/TruckingOffice/bleleak_pub
There are some values in BleReader that will need to be populated on your end.


Calling this a memory leak may be the wrong terminology, but we can't find a way to call multiple characteristics per second without having memory usage of our app increase to the point of failure. If this app is left to run on a device, it will eventually run out of memory and the app will crash. Making the interval longer (2000ms) slows the growth in memory. Making the interval shorter (200ms) increases the growth in memory.
We haven't seen this happen on android.
Any help or guidance would be greatly appreciated.
Unfortunately I got 404 when I try to open your link... It's seems this account doesn't have any public repositories except react-native-version-number.
I just made it public.
Hey,
I tested your repo with SensorTag and following configuration:
const deviceName = 'SensorTag'
const serviceUUID = 'f000aa10-0451-4000-b000-000000000000'
const characteristic1UUID = 'f000aa11-0451-4000-b000-000000000000'
const characteristic2UUID = 'f000aa12-0451-4000-b000-000000000000'
const characteristic3UUID = 'f000aa13-0451-4000-b000-000000000000'
with Xcode 10.2.1 and iPhone 8 (12.3.1). I didn't spot any obvious memory leaks during 1,5h of testing:

Memory stopped at ~9,5 MB.
Hi,
Thanks for the response. We ordered a SensorTag and should have it tomorrow. So, we can try to reproduce your results.
Xcode 10.2.1, iPad mini 4 (12.2)
Profiling in Instruments

Monitoring in XCode (Release build)


Our testing looks like this for multiple users and many different devices. No matter how we run this, we see persistent memory growth. We are wondering if it may have to do with the data type of the BLE characteristic. The characteristics we are reading are strings.
@andycamp
On Friday I had time to look into this memory leak issue. I started by using your example application (bleleak586) and I modified it a little bit for my needs:
With these changes, I tested a few scenarios during a 5 min period of time:
BleModule.swift:660 and replaced it with Observable.just(characteristic): ~44,5MB to ~57,3-58,2 MB.BleClient.m:243 with simple resolve(@{@"value": @"test2"}) function call: ~44,5MB to ~53,5 MB.It was weird for me that these changes didn't have any major impact on memory leakage. Just to be sure I created the same example application, but without intermediate RN bridge. I used the same API which is present in BleClient.m file. After a few attempts I didn't spot any obvious memory leaks - memory usage stayed constant at ~44,5MB.
Afterward, I reimplemented readCharacteristicForDevice as follows:
RCT_EXPORT_METHOD(readCharacteristicForDevice:(NSString*)deviceIdentifier
serviceUUID:(NSString*)serviceUUID
characteristicUUID:(NSString*)characteristicUUID
transactionId:(NSString*)transactionId
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
NSMutableString *string = [NSMutableString new];
for (int i = 0; i < 10000; i++) {
[string appendString:@"very long string..."];
}
NSDictionary* value = @{@"value": @"test2", @"something": string};
resolve(value);
}
... and memory was skyrocketing.
I concluded that whole bridge implementation retains resolved value even though it doesn't have to - it's converted to C++ object. I will try to check it further on Wednesday.
Hi? Does anyone have any updates on this issue? It is a serious dealbreaker for many apps, and it is driving us away from potentially using this library
Hi,
There haven't been any updates to this issue in a while. We tried the ble leak repo with react native 60.5 and ble-plx 1.1.0. It still has the same problem.
+1
we are (@julioxavierr and I) having a similar issue on iOS... in our particular case, we have to send writeCharacteristicWithoutResponseForDevice every ~1s. every time this method is called, the memory usage increases and keeps increasing to the point that, after 5 min, the app is using ~300MB.
react 16.8.3
react-native 0.59.10
react-native-ble-plx 1.1.0
+
If someone is struggling with this, updating react-native to 0.61.2 fixed the problem for us, ran a session that kept communicating with BLE devices during 7 hours. Worth a try.
It was happening with both platforms since we updated to 0.59+.
This is great news! We cannot yet confirm that this resolves the issue and will be waiting for further feedback. Thank you @julioxavierr
This also appears to be fixed for me too. I think there's a typo in the react native version. I tested using react-native 0.61.2. Memory stays constant when reading lots of characteristics.
Can we close this one @Cierpliwy ?
We have had no problems in production with react native 61.2 and ble-plx 1.1.0.
I guess we can.
Most helpful comment
If someone is struggling with this, updating react-native to 0.61.2 fixed the problem for us, ran a session that kept communicating with BLE devices during 7 hours. Worth a try.
It was happening with both platforms since we updated to 0.59+.