0

我通过 SWIG 向 java 公开一个 C++ 类。我在 valgrind 中分别分析了 C++ 类,它没有显示内存泄漏问题。但是当在 valgrind 下运行 swig 生成的 JNI java 类时,它会报告一些内存泄漏。

这就是我调用 valgrind 的方式

LD_LIBRARY_PATH=/lib64/:. valgrind --trace-children=yes --smc-check=all --leak-check=full --show-reachable=yes java -Djava.compiler=NONE -Djava.library.path=.:/lib64/ -classpath yCRF.jar:。测试YCRF

Valgrind 错误如下

==30758== 18 个块中的 147,456 个字节在 731 的丢失记录 729 中仍然可以到达
==30758== 在 0x4A069EE:malloc (vg_replace_malloc.c:270)
==30758== by 0x59927F6: os::malloc(unsigned long) (在/home/y/libexec64/jdk1.7.0/jre/lib/amd64/server/libjvm.so)
==30758== by 0x5489FCE: AllocateHeap(unsigned long, char const*) (在/home/y/libexec64/jdk1.7.0/jre/lib/amd64/server/libjvm.so)
==30758== by 0x57387A4: Hashtable::new_entry(unsigned int, Symbol*) (在/home/y/libexec64/jdk1.7.0/jre/lib/amd64/server/libjvm.so)
==30758== by 0x5A7D782: SymbolTable::basic_add(constantPoolHandle, int, char const**, int*, int*, unsigned int*, Thread*) (在/home/y/libexec64/jdk1.7.0/jre/ lib/amd64/server/libjvm.so)
==30758== by 0x5A7DBAF: SymbolTable::add(constantPoolHandle, int, char const**, int*, int*, unsigned int*, Thread*) (in /home/y/libexec64/jdk1.7.0/jre/ lib/amd64/server/libjvm.so)
==30758== by 0x55CE041: ClassFileParser::parse_constant_pool_entries(constantPoolHandle, int, Thread*) (在/home/y/libexec64/jdk1.7.0/jre/lib/amd64/server/libjvm.so)
==30758== by 0x55D26CF: ClassFileParser::parse_constant_pool(Thread*) (在/home/y/libexec64/jdk1.7.0/jre/lib/amd64/server/libjvm.so)
==30758== by 0x55D4D2D: ClassFileParser::parseClassFile(Symbol*, Handle, Handle, KlassHandle, GrowableArray*, TempNewSymbol&, bool, Thread*) (in /home/y/libexec64/jdk1.7.0/jre/lib/amd64 /server/libjvm.so)
==30758== by 0x55D9234: ClassLoader::load_classfile(Symbol*, Thread*) (in /home/y/libexec64/jdk1.7.0/jre/lib/amd64/server/libjvm.so)
==30758== by 0x5A87196: SystemDictionary::load_instance_class(Symbol*, Handle, Thread*) (in /home/y/libexec64/jdk1.7.0/jre/lib/amd64/server/libjvm.so)
==30758== by 0x5A87980: SystemDictionary::resolve_instance_class_or_null(Symbol*, Handle, Handle, Thread*) (在/home/y/libexec64/jdk1.7.0/jre/lib/amd64/server/libjvm.so)
==30758==
==30758== 1 个块中的 160,088 个字节在 731 的丢失记录 730 中仍然可以访问
==30758== 在 0x4A069EE:malloc (vg_replace_malloc.c:270)
==30758== by 0x59927F6: os::malloc(unsigned long) (在/home/y/libexec64/jdk1.7.0/jre/lib/amd64/server/libjvm.so)
==30758== by 0x5AD4016: Universe_init() (在/home/y/libexec64/jdk1.7.0/jre/lib/amd64/server/libjvm.so)
==30758== by 0x5757D24: init_globals() (在/home/y/libexec64/jdk1.7.0/jre/lib/amd64/server/libjvm.so)
==30758== by 0x5ABB051: Threads::create_vm(JavaVMInitArgs*, bool*) (在/home/y/libexec64/jdk1.7.0/jre/lib/amd64/server/libjvm.so)
==30758== 0x57B7C33:JNI_CreateJavaVM(在 /home/y/libexec64/jdk1.7.0/jre/lib/amd64/server/libjvm.so 中)
==30758== 由 0x4C3DF8D:JavaMain(在 /home/y/libexec64/jdk1.7.0/jre/lib/amd64/jli/libjli.so 中)
==30758== by 0x311F607850: start_thread (pthread_create.c:301)
==30758== 由 0x607A6FF: ???
==30758==
==30758== 1 个块中的 456,768 字节在 731 的丢失记录 731 中仍然可以访问
==30758== 在 0x4A0577B: calloc (vg_replace_malloc.c:593)
==30758== by 0x66F3AC5: readCEN (在/home/y/libexec64/jdk1.7.0/jre/lib/amd64/libzip.so)
==30758== 0x66F4295:ZIP_Put_In_Cache0(在 /home/y/libexec64/jdk1.7.0/jre/lib/amd64/libzip.so 中)
==30758== by 0x55DA3F8: ClassLoader::create_class_path_entry(char*, stat, ClassPathEntry**, bool) (在/home/y/libexec64/jdk1.7.0/jre/lib/amd64/server/libjvm.so)
==30758== by 0x55DB1BE: LazyClassPathEntry::open_stream(char const*) (在/home/y/libexec64/jdk1.7.0/jre/lib/amd64/server/libjvm.so)
==30758== by 0x55D91B8: ClassLoader::load_classfile(Symbol*, Thread*) (in /home/y/libexec64/jdk1.7.0/jre/lib/amd64/server/libjvm.so)
==30758== by 0x5A87196: SystemDictionary::load_instance_class(Symbol*, Handle, Thread*) (in /home/y/libexec64/jdk1.7.0/jre/lib/amd64/server/libjvm.so)
==30758== by 0x5A87980: SystemDictionary::resolve_instance_class_or_null(Symbol*, Handle, Handle, Thread*) (在/home/y/libexec64/jdk1.7.0/jre/lib/amd64/server/libjvm.so)
==30758== by 0x5A8869E: SystemDictionary::initialize_preloaded_classes(Thread*) (在/home/y/libexec64/jdk1.7.0/jre/lib/amd64/server/libjvm.so)
==30758== by 0x5AD4603: Universe::genesis(Thread*) (在/home/y/libexec64/jdk1.7.0/jre/lib/amd64/server/libjvm.so)
==30758== by 0x5AD4AB3: Universe2_init() (在/home/y/libexec64/jdk1.7.0/jre/lib/amd64/server/libjvm.so)
==30758== by 0x5757D7C: init_globals() (在/home/y/libexec64/jdk1.7.0/jre/lib/amd64/server/libjvm.so)
==30758==
==30758== 泄漏摘要:
==30758== 肯定丢失了:31 个块中的 3,952 个字节
==30758== 间接丢失:13 个块中的 4,832 个字节
==30758== 可能丢失:399 个块中的 163,507 个字节
==30758== 仍然可以访问:9,354 个块中的 1,491,202 个字节
==30758== 抑制:0 个块中的 0 个字节

完整的 valgrind 输出可以在这里访问https://www.dropbox.com/s/ybx7e2nv5z0gqzi/valgrind.txt

我试图了解这些泄漏的性质。他们似乎没有指向我的代码。这些真的是我应该担心的错误,还是因为一些 JNI 怪癖而导致 valgrind 表现得很疯狂?

编辑 我尝试了一个没有任何 JNI 组件的简单 java 代码。

//import com.ycrf.Translit;

import java.util.List;
import java.util.Arrays;
import java.util.ArrayList;

public class testYCRF {

public static void main(String[] argv) throws InterruptedException {
    List<String> words =
        Arrays.asList("hum", "jithine", "baap", "chasen"
                //"beti", "beta", "pragya", "hamara",
                //"tumara", "hindu", "hindi", "english"
                // "aag", "atulya", "ataah",
                //"adeergha",  "angootha", "ankan", "ankaganit"
                );

    //Translit tr = new Translit("../../tests/train-crf50K.model");
    for (String word : words) {
        //obj.transliterateWord(word);
    String transliterations = "boo";
        //tr.getTransliterations(word);
        System.out.println(word + ":" + transliterations);
    }
    //tr.delete();
}

}

我得到了同样的 valgrind 错误

4

0 回答 0