Summary
On Android, releasing an LLMPipeline and then creating a new pipeline in the same app process can crash the process with native SIGSEGV during the next warm-up/create cycle.
This was reproduced from the openvino-notes Android integration that uses genai-java-api as the OpenVINO GenAI Java wrapper.
Environment
- Device: Samsung
SM-S931B (pa1q)
- Android: 16, API 36
- App package:
com.itlab.notes
- Backend: OpenVINO GenAI Java API + Android CPU pipeline
- Model assets are already cached in app storage; the repro does not depend on recopying model assets.
Reproduction observed in openvino-notes
- Start the app and let the LLM warm-up create the pipeline.
- Release AI resources in the live Android process. In Notes this calls through
ReleaseNoteAiUseCase -> NoteAiService.release() -> OpenVinoGenAiBackend.close() -> LLMPipeline.close().
- Return to the app / trigger warm-up again so a new
LLMPipeline is created in the same process.
- The second create/warm-up path reaches
pipelineReady, then the process dies with native signal 11.
A concrete synthetic trigger used during debugging:
adb shell input keyevent HOME
adb shell am send-trim-memory com.itlab.notes BACKGROUND
adb shell am start -W -n com.itlab.notes/.MainActivity
Actual result
The process exits with native signal 11 after close/recreate:
ApplicationExitInfo:
process=com.itlab.notes
reason=2 (SIGNALED)
status=11
importance=100
rss=2.7GB
Relevant app logs from the recreate attempt:
OpenVinoGenAiBackend: createPipeline modelDirReady elapsedMs=4
OpenVinoGenAiBackend: createPipeline runtimeReady elapsedMs=3
OpenVinoGenAiBackend: createPipeline javaApiReady elapsedMs=0
OpenVinoGenAiBackend: createPipeline pipelineReady elapsedMs=18156 ... totalMs=18163
OpenVinoGenAiBackend: warmUp elapsedMs=18163
ActivityManager: Process com.itlab.notes (...) has died: fg TOP
Before the recreate, LLMPipeline.close() did free memory substantially, so disposal itself is doing real native teardown:
Before release: TOTAL PSS about 2.7GB, TOTAL RSS about 2.8GB
After release: TOTAL PSS about 158MB, TOTAL RSS about 284MB
Expected result
One of these should be true:
LLMPipeline.close() safely disposes native resources and a later new LLMPipeline(...) works in the same Android process.
- Or the API explicitly documents that Android
LLMPipeline is process-lifetime only and must not be closed/recreated, and the Java wrapper prevents unsafe reuse patterns where possible.
Current workaround in openvino-notes
openvino-notes temporarily avoids calling LLMPipeline.close() from normal app lifecycle/memory-trim paths. The pipeline is prepared once per live app process and kept alive to avoid the crash. This keeps the app stable, but leaves high native memory resident while the process is alive.
Suspected area
Likely candidates:
LLMPipeline.close() / NativeResource lifecycle in Java wrapper.
- JNI disposal path around
PipelineHandle / ov::genai::LLMPipeline destruction.
- OpenVINO GenAI Android runtime state that is not fully reusable after pipeline teardown.
A smaller dedicated Android smoke test should probably cover:
initialize runtime
create LLMPipeline
optionally generate a short response
close LLMPipeline
create LLMPipeline again in the same process
optionally generate a short response again
Summary
On Android, releasing an
LLMPipelineand then creating a new pipeline in the same app process can crash the process with nativeSIGSEGVduring the next warm-up/create cycle.This was reproduced from the
openvino-notesAndroid integration that usesgenai-java-apias the OpenVINO GenAI Java wrapper.Environment
SM-S931B(pa1q)com.itlab.notesReproduction observed in openvino-notes
ReleaseNoteAiUseCase -> NoteAiService.release() -> OpenVinoGenAiBackend.close() -> LLMPipeline.close().LLMPipelineis created in the same process.pipelineReady, then the process dies with native signal 11.A concrete synthetic trigger used during debugging:
Actual result
The process exits with native signal 11 after close/recreate:
Relevant app logs from the recreate attempt:
Before the recreate,
LLMPipeline.close()did free memory substantially, so disposal itself is doing real native teardown:Expected result
One of these should be true:
LLMPipeline.close()safely disposes native resources and a laternew LLMPipeline(...)works in the same Android process.LLMPipelineis process-lifetime only and must not be closed/recreated, and the Java wrapper prevents unsafe reuse patterns where possible.Current workaround in openvino-notes
openvino-notestemporarily avoids callingLLMPipeline.close()from normal app lifecycle/memory-trim paths. The pipeline is prepared once per live app process and kept alive to avoid the crash. This keeps the app stable, but leaves high native memory resident while the process is alive.Suspected area
Likely candidates:
LLMPipeline.close()/NativeResourcelifecycle in Java wrapper.PipelineHandle/ov::genai::LLMPipelinedestruction.A smaller dedicated Android smoke test should probably cover: