Database features
Feature is an interface allowing to store and query additional information based on bytecode.
Feature can be installed only upon creating the JacoDB instance.
var db = JacoDb.async(new JcSettings() .useProcessJRE() .persistent("/tmp/compilation-db/${System.currentTimeMillis()}") // persist data .installFeatures(Usages.INSTANCE, InMemoryHierarchy.INSTANCE) ).get();
InMemoryHierarchy
By default, JacoDB stores information about class hierarchy in an SQL database (the ClassHierarchies table with
the columns: class_id, super_id, is_interface). It allows us to retrieve the hierarchy for a particular class
with a recursive SQL query. Recursive queries are rather common and rather slow.
InMemoryHierarchy solves a performance problem of a built-in solution. It introduces a fast-search in-memory cache.
Memory overhead is O(number of classes). For the project with about 50K classes (including runtime) memory consumption for such a cache is ~6.5 Mb of heap memory.
Usages
You can find places where methods and fields are used.
For better performance, install InMemoryHierarchy.
var db = JacoDb.async(new JcSettings() .useProcessJRE() .persistent("/tmp/compilation-db/${System.currentTimeMillis()}") // persist data .installFeatures(Usages.INSTANCE, InMemoryHierarchy.INSTANCE) ).get(); var method = run; // java.lang.Runnable#run method var field = field; // java.lang.String#value field var cp = db.asyncClasspath(allClasspath).get(); cp.findUsages(method); // sequence of methods which calls method cp.findUsages(field, FieldUsageMode.READ); // sequence of fields which reads field value
The Usages indexer goes through all instructions, collects information on method calls or field access, and
stores it in a table:
| Column name | Column description |
|---|---|
| callee_class_symbol_id | a unique identifier for the callee class name |
| callee_name_symbol_id | a method/field name unique identifier |
| callee_desc_hash | null for field usage; Sip hash of method bytecode, description for methods |
| opcode | instruction operation code |
| caller_class_symbols_id | a unique identifier for the caller class name |
| caller_method_offsets | method numbers for this usage |
| location_id | a location identifier |