Skip to content

GH-1205: Fix byte-array element leak in FromSchemaByteArray - #1249

Open
PG1204 wants to merge 2 commits into
apache:mainfrom
PG1204:gh-1205-fix-schema-bytearray-leak
Open

GH-1205: Fix byte-array element leak in FromSchemaByteArray#1249
PG1204 wants to merge 2 commits into
apache:mainfrom
PG1204:gh-1205-fix-schema-bytearray-leak

Conversation

@PG1204

@PG1204 PG1204 commented Jul 24, 2026

Copy link
Copy Markdown

What's Changed

FromSchemaByteArray() in dataset/src/main/cpp/jni_util.cc acquires the Java byte-array elements via GetByteArrayElements(), but the matching ReleaseByteArrayElements() was only reached on the success path. When arrow::ipc::ReadSchema() failed, ARROW_ASSIGN_OR_RAISE returned early and skipped the release, leaking the pinned/copied array buffer on every call with malformed or incompatible serialized schema bytes (e.g. via createDataset()).

This releases the elements through an RAII guard so they are always freed on every exit path - success or error, and stays correct if additional early returns are added later.

Also adds a regression test (TestFromSchemaByteArray) that repeatedly drives the native createDataset path with malformed schema bytes, exercising the former leak branch and asserting it fails gracefully with an exception rather than crashing.

Closes #1205.

@github-actions

This comment has been minimized.

@xborder

xborder commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Seems reasonable. From what I was researching, doesn't seem like it is a leak easy to hit and it may only leak a few KBs.

I'd probably just try to add a test that reproduces the issue an ensure that it passes with the fix

@PG1204

PG1204 commented Jul 25, 2026

Copy link
Copy Markdown
Author

Seems reasonable. From what I was researching, doesn't seem like it is a leak easy to hit and it may only leak a few KBs.

I'd probably just try to add a test that reproduces the issue an ensure that it passes with the fix

@xborder Agreed it's low-impact and hard to hit. I've added a regression test (TestFromSchemaByteArray) that feeds malformed schema bytes to the native createDataset path, which is the exact branch that used to skip ReleaseByteArrayElements, and confirms it now fails gracefully with the fix in place.

@lidavidm lidavidm added the bug-fix PRs that fix a big. label Jul 25, 2026
@github-actions github-actions Bot added this to the 20.0.0 milestone Jul 25, 2026
@xborder

xborder commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

@PG1204 I don't think this is testing that we fixed the memory leak. This is just testing the error is thrown. Shouldn't it check no memory was leaked?

@PG1204

PG1204 commented Jul 31, 2026

Copy link
Copy Markdown
Author

@PG1204 I don't think this is testing that we fixed the memory leak. This is just testing the error is thrown. Shouldn't it check no memory was leaked?

@xborder you're right, that only proves the error path is hit, not that the leak is gone. The catch is what leaks: the buffer wraps the pointer from GetByteArrayElements, which on HotSpot copies the array into a JVM-internal malloc'd buffer, and that copy is what leaked. It's not tracked by NativeMemoryPool, not on the Java heap, and has no portable Java API; it's only visible via process RSS.

So the only way I see to assert "no leak" from Java is an RSS-growth check: loop the call many times with a large payload and assert RSS stays bounded (unfixed balloons by GBs, fixed stays flat). That works on Linux but needs gating on macOS/Windows and is a bit flaky.

Would you prefer (1) that RSS-based test, or (2) dropping the Java assertion and verifying manually with a local leak-checker (valgrind/ASAN), keeping the current test as a graceful-failure guard? Note CI doesn't run a sanitizer today, so option 2 wouldn't be enforced automatically. Happy either way, just want to avoid landing a flaky test.

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

Labels

bug-fix PRs that fix a big.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Byte-array elements leak in FromSchemaByteArray()

3 participants