Утечка памяти в неизвестном модуле сообщается с помощью JNA и JUnitJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Утечка памяти в неизвестном модуле сообщается с помощью JNA и JUnit

Сообщение Anonymous »

Это конкретная проблема, которую я обнаружил при создании MRE для моего предыдущего вопроса. Неясно, является ли это той же самой проблемой, хотя она кажется связанной, поэтому я задаю ее как отдельный вопрос.
Рассмотрим следующий тестовый класс JUnit:
Рассмотрим следующий тестовый класс JUnit:
p>

Код: Выделить всё

import com.sun.jna.Memory;
import com.sun.jna.Pointer;
import java.lang.Integer;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.Test;

public class MyTest {
private void dummyTest() {
new Memory(1024 * 9);
}

@Test
public void find() {
List list = new ArrayList();
list.add(new Integer(1));

list.stream().map(arg -> {
Pointer ptr = new Memory(1024 * 1024);
return ptr;
}).toArray(Pointer[]::new);
}

@Test
public void test001() {
dummyTest();
}

// [91 more identical tests named test002...test092 follow]
Я запускаю его на Docker Ubuntu 24.04 с пакетами openjdk-8-jdk clang-17, используя Gradle, с предварительно загруженным дезинфицирующим средством адресов. JNA 5.12.1, JUnit 5.8.2, хост-система — последняя версия Arch Linux. Скрипт для его запуска:

Код: Выделить всё

echo -e "leak:libjvm\nleak:libjli\nleak:libz\nleak:liblcms\nleak:liblcms2\nleak:libjavalcms\nleak:libawt\n" >> lsan.supp
export LD_PRELOAD="/usr/lib/llvm-17/lib/clang/17/lib/linux/libclang_rt.asan-x86_64.so"
export ASAN_OPTIONS="handle_segv=0"
export LSAN_OPTIONS="suppressions="$(pwd)"/lsan.supp:print_suppressions=0"

./gradlew clean test
Он постоянно выдает следующий отчет об утечке:

Код: Выделить всё

Direct leak of 1048576 byte(s) in 1 object(s) allocated from:
#0 0x759245cfb372 in malloc (/usr/lib/llvm-17/lib/clang/17/lib/linux/libclang_rt.asan-x86_64.so+0xfb372) (BuildId: 91f375f2a48c6b133a56d8cc059d017ae5de4982)
#1 0x7592316185e6  ()
#2 0x759231607bcf  ()
#3 0x759231607bcf  ()
#4 0x7592316080f5  ()
#5 0x759231607e3f  ()
#6 0x75923197befb  ()

SUMMARY: AddressSanitizer: 1048576 byte(s) leaked in 1 allocation(s).
Это явно относится к собственной памяти, выделенной в строке 19. Поскольку экземпляр Memory должен освобождать собственную память в gc, я не думаю, что это настоящая утечка - скорее, похоже, что JNA выгружается до того, как это произойдет. Однако:
  • избавление от ArrayList,stream и toArray и непосредственное создание Pointer[] ptrs = new Указатель[1]; ptrs[0] = new Memory(1024 * 1024); приводит к исчезновению отчета об утечке
  • уменьшение количества фиктивных тестов приводит к исчезновению отчета об утечке, в зависимости от точного количества
  • изменение названий тестов может привести к исчезновению отчета об утечке
Собственная память malloc никогда не затрагивается в моем коде, поэтому я учитывая возможность странного поведения, связанного с чрезмерным выделением памяти.
Это также может быть связано с порядком тестов, определенным JUnit. Это единственное объяснение, почему имена тестов имеют значение.
Я создал полный репозиторий, чтобы удобно воспроизвести эту ошибку, вызвав run.sh. Вся соответствующая информация и код копируются в этот вопрос.
Мой вопрос: что именно вызывает этот конкретный отчет об утечке?

Подробнее здесь: https://stackoverflow.com/questions/793 ... -and-junit
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»