apache / apache/arrow-java

[Java] VectorUnloader has multiple memory leak issues

Aberta
#1,234 3 comentários 0 reações 0 responsáveis Ver no GitHub
Type: bug
Linguagem predominante
Java
Estrelas
94
Forks
152
Merge médio
3d 16h
PRs com merge (30d)
11

Descrição

### Describe the bug, including details regarding any error messages, version, and platform.

### Problem Description

The VectorUnloader class has serious memory leak issues when serializing Vector data. Any exception thrown during the process will cause previously retained ArrowBuf instances to never be released.
Root Cause
ArrowBuf uses reference counting for memory management. After calling retain(), a corresponding release() must be called to free the buffer. The code has exception-safety defects in multiple locations:

---
#### Bug 1: OOM during compression causes leak
```
Location: appendNodes() method, around line 75
buf.getReferenceManager().retain();
buffers.add(codec.compress(vector.getAllocator(), buf)); // OOM here causes leak
Problem: If codec.compress() throws OutOfMemoryError, retain() has already been called but buffers.add() never executes, making the ArrowBuf unreleasable.
```
---
#### Bug 2: Compression failure in loop causes partial leak
```
Location: appendNodes() method, around lines 78-85
for (ArrowBuf buf : fieldBuffers) {
buf.getReferenceManager().retain();
buffers.add(codec.compress(vector.getAllocator(), buf)); // Any failure leaks all previously retained buffers
}
Problem: Any compression failure in the loop causes all previously retained buffers to leak.
```
---
#### Bug 3: Exception during recursive child vector processing causes leak
```
Location: appendNodes() method, around lines 87-89
for (FieldVector child : vector.getChildrenFromFields()) {
appendNodes(child, nodes, buffers, variadicBufferCounts); // Exception here leaks buffers from current level
}
Problem: An exception during recursive child processing prevents release of buffers already retained at the current level.
```
---
#### Bug 4: Iteration failure in top-level loop causes cumulative leaks
```
Location: getRecordBatch() method, around lines 53-58
for (FieldVector vector : root.getFieldVectors()) {
appendNodes(vector, nodes, buffers, variadicBufferCounts); // Any failure leaks all previously retained buffers
}
Problem: Each iteration retains buffers, and any failure causes cumulative leaks of all previously retained buffers. This is an accumulated leak.
```
---
### Impact
- All code using VectorUnloader.getRecordBatch()
- Leak probability increases significantly when processing large datasets or when compressor runs low on memory
- Leaked ArrowBuf instances persist until process termination
Suggested Fix
1. Use try-finally to ensure release() is called even when exceptions occur
2. Or add buffers to the list before calling retain() and compress()
3. Use transactional error handling for the entire getRecordBatch() operation, rolling back all buffers on failure

Guia de contribuição

Abrir o guia de contribuição

Direção de pesquisa

Comece pela classe VectorUnloader, concentrando-se em getRecordBatch() e appendNodes(), especialmente nos caminhos de retain(), compress() e processamento recursivo de filhos descritos na issue. Verifique se as falhas em cada local liberam todos os ArrowBuf retidos, incluindo os buffers de iterações anteriores, e confirme que a serialização normal de record batches continua funcionando.

Escrita pelo modelo de indexação a partir do texto da issue.

Avaliação

Stack de tecnologia
java
Domínio
data
Tipo de issue
Bug
Dificuldade
4/5
Tempo estimado
3-5 dias
Status de atividade
Pouca atividade
Clareza
Claramente especificada
Facilidade para iniciantes
62/100

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.