margelo / margelo/react-native-vision-camera
🐛 Android: every <Camera> mount leaks its SurfaceView and camera output stream
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 9.6k
- Forks
- 1.4k
- Avg merge
- 1d 28m
- Merged PRs (30d)
- 4
Description
Prerequisites
- I have read and followed every applicable step in the Nitro Modules Troubleshooting guide.
- I have read the VisionCamera Troubleshooting guide.
- I have searched existing issues and found nothing matching.
- I am on the latest version of react-native-vision-camera, or have a specific reason I cannot upgrade.
Reproduction
https://github.com/Gogn/react-native-vision-camera_issue-reproducing
Steps to reproduce
- Clone the attached repository or create a bare React-Native project
- Run the app
- Watch logcat:
adb logcat | grep -E "SurfaceView\[|BufferQueue has been abandoned|Camera3-OutputStream" - Optionally check a heap dump:
adb shell am dumpheap com.vcpreviewleak /something/heap.hprof
What did you expect to happen?
Mounting and unmounting a screen with <Camera> should release the SurfaceView and its camera output stream. After some time, the number of live SurfaceView / PreviewView / HybridPreviewView instances should stay at the same amount regardless of how many times the component is mounted.
What actually happened?
Every mount leaks the preview's SurfaceView and creates a new camera output stream, nothing is released. After the surface is destroyed on unmount, the camera pipeline keeps trying to queue buffers into the abandoned BufferQueue.
With every new mount/unmount cycle:
- a new
SurfaceViewsurface is created and the previous one is never released - Those surfaces emitts
BufferQueue has been abandonederrors after being destroyed - a new camera3 output stream is created
- just one
MainActivitythroughout, so this is not an Activity leak
Affected platforms
Android (emulator)
Device(s) affected
Android 11 emulator, arm64-v8a
VisionCamera version
5.2.3
React Native version
0.86.3
React Native architecture
New Architecture (Fabric / bridgeless)
Features being used
- Preview
- Photo capture
- Video capture
- Frame Processors (worklets)
- Skia Frame Processors
- Code/Barcode Scanner
- Location metadata
- Multi-cam
- Depth data
- HDR / custom dynamic range
- Custom format / FPS / resolution
Relevant logs / stack trace
One cycle, showing the surface being destroyed and then still written to:
D SurfaceViewImpl: Surface destroyed.
D SurfaceViewImpl: Surface closed androidx.camera.core.SurfaceRequest@f6f2cf
E BufferQueueProducer: [1e02dbf SurfaceView[com.vcpreviewleak/com.vcpreviewleak.MainActivity]#431(BLAST Consumer)431](id:7f8e000001af,api:4,p:596,c:32654) queueBuffer: BufferQueue has been abandoned
E Surface : queueBuffer: error queuing buffer, -19
D StreamStateObserver: Update Preview stream state to IDLE
I HybridPreviewViewSpec: PreviewView stopped!
E Camera3-OutputStream: returnBufferCheckedLocked: Stream 544: Error queueing buffer to native window: No such device (-19)
E Camera3-OutputStream: getBufferLockedCommon: Stream 544: Can't dequeue next output buffer: No such device (-19)
D CXCP : Closing capture session for CaptureSessionState-432
Heap dump after 30 cycles (app heap only):
31 com.margelo.nitro.camera.views.HybridPreviewView
31 com.margelo.nitro.camera.hybrids.outputs.HybridPreviewOutput
25 com.margelo.nitro.camera.hybrids.HybridCameraSession
25 com.margelo.nitro.camera.hybrids.HybridCameraController
9 com.margelo.nitro.camera.hybrids.inputs.HybridCameraDevice
Additional context
- Seems not a duplicate of #4095. That issue was fixed by nitro#1460 and the fix is working here.
- In our app the leaked
SurfaceViewsits inside a navigation screen, so it pins thereact-native-screensand that screen whole view hierarchy. The leak becomes Java heap growth.
Submission
- The reproduction I linked is either (preferred) a PR against this repo that adds a failing harness test following the harness-tests README, or (fallback) a public repo that reproduces the bug on a fresh clone. I understand the issue will be closed without one.
- I pasted logs as text (not screenshots).
- I wrote this report in my own words. I did not paste AI-generated descriptions of the bug.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the linked reproduction repository and run the app while observing the provided adb logcat filter. Use the heap-dump command and the harness-tests README in apps/simple-camera/tests to compare repeated Camera mount/unmount cycles. Done means old SurfaceView and camera output instances are released without BufferQueue or Camera3-OutputStream errors.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- android
- Domain
- mobile-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100