Я не могу воспроизвести ошибку на каком-то минимальном рабочем примере, потому что ошибка связана с выполнением сложных операций чтения в библиотеке c ++.Тем не менее, я выполнил несколько тестов и могу описать результаты двух возможных конфигураций.
У меня есть некоторый Java-код, который выполняет поиск в файлах (сериализованных в двоичном формате) через класс (а именно, JNIClass)доступ к библиотеке C ++ через JNI.
JNIClass используется внутри Consumer, примененного к методам forEach потоков java.Потоки могут быть как потоками, так и параллельными потоками.Я заметил некоторые ошибки только тогда, когда такие потоки являются параллельными, а библиотека c ++ выполняет только чтение и двоичный поиск по сериализованной структуре данных, а структура данных с выделением кучи не выделяется.Единственное, что разделяется между потоками, это некоторый указатель на функцию для сравнения для бинарного поиска.Итак, мне интересно, почему операция только для чтения, которая возвращает результат поиска в Java, может вызвать такие проблемы.
Я думал о возможном решении, но я не знаю, возможно ли это в Java: развязает ли связьбиблиотека c ++ и привязка каждого потока к другому файлу библиотеки решит проблему доступа к памяти?Является ли совместное использование вышеупомянутого указателя функции для двоичного поиска источником проблем?
РЕДАКТИРОВАНИЕ
Дамп ядра (gdb java core
):
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `/usr/lib/jvm/java-8-oracle/bin/java -Xmx60g -javaagent:/media/giacomo/Data/Scar'.
Program terminated with signal SIGABRT, Aborted.
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51 ../sysdeps/unix/sysv/linux/raise.c: File o directory non esistente.
[Current thread is 1 (Thread 0x7f48473ec700 (LWP 8542))]
(gdb) where
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1 0x00007f57775a1801 in __GI_abort () at abort.c:79
#2 0x00007f5776e8e3c5 in os::abort(bool) () from /usr/lib/jvm/java-8-oracle/jre/lib/amd64/server/libjvm.so
#3 0x00007f57770325b3 in VMError::report_and_die() () from /usr/lib/jvm/java-8-oracle/jre/lib/amd64/server/libjvm.so
#4 0x00007f5776e9470f in JVM_handle_linux_signal () from /usr/lib/jvm/java-8-oracle/jre/lib/amd64/server/libjvm.so
#5 0x00007f5776e8a653 in signalHandler(int, siginfo*, void*) () from /usr/lib/jvm/java-8-oracle/jre/lib/amd64/server/libjvm.so
#6 <signal handler called>
#7 0x00007f48462ffb4d in SLHM_Secondary::searchForId (this=0x7f47640179b8, toSearch="elias delta coding") at /home/giacomo/CLionProjects/edgeindexing/fmatch/StringLongHashMultimapIndexer/SLHM_Secondary.cpp:34
#8 0x00007f4846300c14 in FuzzyMatch_FDContainer::rankCollectionOf (this=0x7f47640179b8, k=std::unordered_set with 368560 elements = {...}, m1=std::unordered_map with 10 elements = {...}, size=10,
threshold=0.69999999999999996, pollMap=...) at /home/giacomo/CLionProjects/edgeindexing/fmatch/FuzzyMatch_FDContainer.cpp:123
#9 0x00007f4846301483 in FuzzyMatch_FDContainer::fuzzyMatch (this=0x7f47640179b8, threshold=0.69999999999999996, topk=3, objectString="105th Brigade", result=std::multimap with 0 elements)
at /home/giacomo/CLionProjects/edgeindexing/fmatch/FuzzyMatch_FDContainer.cpp:181
#10 0x00007f4846301792 in FuzzyMatch_FDContainer::fuzzyMatch (this=0x7f47640179b8, threshold=0.69999999999999996, topk=3, objectStrings="105th Brigade")
at /home/giacomo/CLionProjects/edgeindexing/fmatch/FuzzyMatch_FDContainer.cpp:213
#11 0x00007f48462e82dc in Java_org_ufl_hypogator_jackb_fuzzymatching_TwoGramIndexerJNI_fuzzyMatch (env=0x7f475c0029f8, self=0x7f48473ead48, dim=0x7f48473ead40, threshold=0.69999999999999996, topk=3,
term=0x7f48473ead20) at /home/giacomo/CLionProjects/edgeindexing/fmatch/libfuzzymatch.cpp:48
#12 0x00007f5761018687 in ?? ()
#13 0x00007f48473eac90 in ?? ()
#14 0x00007f484f906ad0 in ?? ()
#15 0x00007f48473eacf0 in ?? ()
#16 0x00007f484f9089a8 in ?? ()
#17 0x0000000000000000 in ?? ()
Информация о стеке из файла .log
:
Stack: [0x00007f71eb8fd000,0x00007f71eb9fe000], sp=0x00007f71eb9fa620, free space=1013k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [libc.so.6+0x97207] __libc_malloc+0x197
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j sun.misc.Unsafe.defineAnonymousClass(Ljava/lang/Class;[B[Ljava/lang/Object;)Ljava/lang/Class;+0
j java.lang.invoke.InnerClassLambdaMetafactory.spinInnerClass()Ljava/lang/Class;+511
j java.lang.invoke.InnerClassLambdaMetafactory.buildCallSite()Ljava/lang/invoke/CallSite;+1
j java.lang.invoke.LambdaMetafactory.metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;+31
j java.lang.invoke.LambdaForm$DMH.invokeStatic_L6_L(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;+20
j java.lang.invoke.LambdaForm$BMH.reinvoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;+79
j java.lang.invoke.LambdaForm$MH.invoke_MT(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;+30
j java.lang.invoke.CallSite.makeSite(Ljava/lang/invoke/MethodHandle;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/invoke/CallSite;+184
j java.lang.invoke.MethodHandleNatives.linkCallSiteImpl(Ljava/lang/Class;Ljava/lang/invoke/MethodHandle;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/invoke/MemberName;+6
j java.lang.invoke.MethodHandleNatives.linkCallSite(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/invoke/MemberName;+45
v ~StubRoutines::call_stub
j org.ufl.hypogator.jackb.scraper.adt.DiGraphEquivalenceClass.loadFromFile2(Ljava/io/File;Lorg/ufl/hypogator/jackb/disambiguation/dimension/concept/ConceptNetVocabulary;Ljava/util/function/Function;)V+11
j org.ufl.hypogator.jackb.fuzzymatching.TwoGramIndexerJNI$TwoGramIndexerForDimension.<init>(Lorg/ufl/hypogator/jackb/fuzzymatching/TwoGramIndexerJNI;Ljava/lang/String;Lorg/ufl/hypogator/jackb/fuzzymatching/TwoGramIndexerJNI;)V+89
j org.ufl.hypogator.jackb.fuzzymatching.TwoGramIndexerJNI.openDimension(Ljava/lang/String;)Lorg/ufl/hypogator/jackb/fuzzymatching/TwoGramIndexerJNI$TwoGramIndexerForDimension;+25
j org.ufl.hypogator.jackb.scraper.MultiConceptScraper$PrivateTermScorer.<init>(Lorg/ufl/hypogator/jackb/scraper/MultiConceptScraper;Ljava/lang/String;Z)V+39
j org.ufl.hypogator.jackb.scraper.MultiConceptScraper.dimension(Ljava/lang/String;Z)Lorg/ufl/hypogator/jackb/scraper/TermScorer;+7
j org.ufl.hypogator.jackb.disambiguation.dimension.concept.ConceptNetDimensionDisambiguationOperations.<init>(Ljava/lang/String;)V+57
j org.ufl.hypogator.jackb.disambiguation.dimension.concept.DisambiguatorForDimensionForConcept.<init>(Ljava/lang/String;)V+2
j org.ufl.hypogator.jackb.disambiguation.dimension.concept.DimConcepts.<init>(Ljava/lang/String;)V+15
j org.ufl.hypogator.jackb.inconsistency.legacy.TupleComparator.generateFromType(Ljava/lang/String;)Lorg/ufl/hypogator/jackb/comparators/partialOrders/InformationPreservingComparator;+117
j org.ufl.hypogator.jackb.m9.CompareOnce.lambda$memoizeTypeComparisons$2(Lorg/jooq/Record;)V+13
j org.ufl.hypogator.jackb.m9.CompareOnce$$Lambda$14.accept(Ljava/lang/Object;)V+4
j java.util.stream.ForEachOps$ForEachOp$OfRef.accept(Ljava/lang/Object;)V+5
j java.util.Spliterators$ArraySpliterator.forEachRemaining(Ljava/util/function/Consumer;)V+53
j java.util.stream.AbstractPipeline.copyInto(Ljava/util/stream/Sink;Ljava/util/Spliterator;)V+32
j java.util.stream.ForEachOps$ForEachTask.compute()V+103
j java.util.concurrent.CountedCompleter.exec()Z+1
j java.util.concurrent.ForkJoinTask.doExec()I+10
j java.util.concurrent.ForkJoinPool$WorkQueue.runTask(Ljava/util/concurrent/ForkJoinTask;)V+21
j java.util.concurrent.ForkJoinPool.runWorker(Ljava/util/concurrent/ForkJoinPool$WorkQueue;)V+35
j java.util.concurrent.ForkJoinWorkerThread.run()V+24
v ~StubRoutines::call_stub
Последняя строка - это код searchForId
, вызывающий ошибку:
void *SLHM_Secondary::searchForId(std::string &toSearch) {
LONG_NUMERIC hash = hashf(toSearch);
struct long_index_file toSearchVehicle{};
toSearchVehicle.id = hash;
struct long_index_file* ptr = binVectorFixedSizeArray<struct long_index_file>(pimarySparseIndex, primarySize, &toSearchVehicle, &findLongIndexOffset);
if (ptr == nullptr) return nullptr;
LONG_NUMERIC* offsets = (LONG_NUMERIC*)(this->element+ptr->offset);
LONG_NUMERIC n = offsets[0]; // Line 34