Skip to content

Possible Windows memory leak in btleplug 0.13.1 #476

Description

@Raphiiko

Describe the bug

Hi, I recently migrated my application OyasumiVR from bluest to btleplug. Since then, I've had reports of memory usage climbing over time on Windows, which I've also reproduced myself with btleplug 0.13.1.

I want to be upfront that this isn't my area of expertise, so I threw Astra at the problem. It came up with a possible cause and patch. I can personally only speak for the before and after results, not the findings or solution, but I figured I'd report it anyway.

Expected behavior

btleplug should release resources when they're no longer needed, without memory accumulating over repeated use.

Actual behavior

I ran the unpatched 0.13.1 build for about eight hours, then the patched build for two hours, with the same five Bluetooth LE devices connected.

Unpatched 0.13.1 With the proposed patch
Duration About 8 hours 2 hours
Private memory at start 53 MiB 53 MiB
Private memory at end 1,477 MiB 56 MiB
Memory growth over matching periods About 182 MiB/hour About 0.37 MiB/hour

Astra calculated the growth rates from the matching first two hours, excluding the first ten minutes. Memory kept growing throughout the unpatched run. With the patch, it stayed below 57 MiB.

All five devices connected in both runs. Neither run logged connection failures during measurement. I haven't tested the patched build for the full eight hours.

Additional context

Setup

  • Windows
  • Intel Wireless Bluetooth, driver 24.30.1.1
  • btleplug 0.13.1
  • Five Bluetooth LE devices

Dump analysis

Astra analyzed memory dumps from both runs using their matching executables and PDBs. It identified the following radio callbacks:

Near the start At the end
Unpatched 18 3,198
Patched 1 1

In the unpatched final dump, it traced those callbacks to 3,198 adapter managers and about 73,000 retained device objects. Those are accumulated objects from repeated discovery, not separate physical devices. Their map storage alone accounted for about 1.17 GiB.

According to its analysis, 3,197 of those managers had only one remaining strong reference, held by a radio callback. It also checked a sample of the callback and manager allocations against Windows heap records.

Suspected cause

Astra's explanation is that the Windows Radio::StateChanged handler remains registered after its adapter is dropped. The callback holds references to the radio and device manager, keeping the manager's device data alive.

The dump findings appear to support that explanation, but I haven't independently verified Astra's interpretation.

Proposed patch

This PR contains the patch Astra implemented for 0.13.1. It removes the radio handler when the last adapter clone is dropped and changes the callback to hold a weak reference to the manager.

The scan-handler cleanup already present in 0.13.1 is unchanged.

I can't vouch for the implementation or whether this is the correct fix. I can only confirm that memory consumption was much lower in my test with it applied. I'd appreciate someone familiar with the Windows implementation taking a look.

Activity

  1. qdot commented on Sep 20, 2026

    @qdot
    Contributor

    Thanks for the PR, and letting me know how it was generated. Funny enough, you've found a 2 year old memory leak! Looks like this goes all the way back to Sept 2024. We'll get this in and 0.13.2 out.

    I think you may've run into this because you're constantly recreating adapters. I'd recommend just holding one for the lifetime of your process if you can, there's not really much of a reason to recreate it afaik.

    Oyasumi looks pretty neat! I'm a daily VRC user but still have never managed any sleep in VR over like 15 minutes heh.

  2. qdot commented on Sep 20, 2026

    @qdot
    Contributor

    PR merged in 0.13.2

  3. Raphiiko commented on Sep 20, 2026

    @Raphiiko
    ContributorAuthor

    Awesome, thanks for getting this sorted so quickly. The adapter recreation was left over from a workaround I needed on 0.12. That seems to no longer be necessary on 0.13, so I’m keeping a single adapter around now.

    Thanks for the nice words! Sleeping in VR definitely takes a little getting used to ^^'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions