owlcs / owlapi

OWL API main repository
821 stars 315 forks source link

How to release memory of OWLOntologyManager instance #1078

Closed fanavarro closed 1 year ago

fanavarro commented 1 year ago

Hi, I am developing an application that performs several calculations on several ontologies. Particularly, I am creating several tasks that are executed through a FixedThreadPool. Each task deal with only one ontology, and each one does something like this:

public Results call() throws Exception {
    /* Create ontology manager */
    OWLOntologyManager ontologyManager = OWLManager.createConcurrentOWLOntologyManager();

    /* Load ontology */
    ontology = ontologyManager.loadOntologyFromOntologyDocument(this.ontologyFile);

    /* Some stuff calculated from the ontology... */
    Results results = doSomethingWithOntology(ontology);

    /* Release memory used by the ontology manager */
    ontologyManager.clearOntologies();
    ontologyManager.getOntologyStorers().clear();
    ontologyManager.getIRIMappers().clear();

    return results;
}

So there will be several threads executing that code at the same time for different ontologies. As ontologies can have a large size, I would like to release the memory used by the ontology manager when I have the results I wanted. For this, I am clearing the ontologies, the ontology storers and the iri mappers, as depicted in the code above. Nonetheless, I am getting the exception:

java.util.concurrent.ExecutionException: java.lang.IllegalStateException: Manager on ontology OntologyID(OntologyIRI(<http://purl.obolibrary.org/obo/geo.owl>) VersionIRI(<null>)) is null; the ontology is no longer associated to a manager. Ensure the ontology is not being used after being removed from its manager.

When I remove the lines concerning to the memory release, this exception is no appearing. So, my question is: how can I release the memory used by the ontology manager? Furthermore, is this necessary? Maybe the java garbage collector is doing this job already.

Thanks for your attention and have a nice day, Fran.

ignazio1977 commented 1 year ago

In the code shown, the manager is created within the thread call and will be disposed of once the call method completes. The fact that you're getting an error about the ontology manager being null makes me suspect that your Results instance is retaining a reference to the ontology, and using methods on it that rely on the manager to complete. Can you share the full stack trace of the error, and the relevant code if possible?

fanavarro commented 1 year ago

Hi @ignazio1977, thanks for your answer! My fault, I've been inspecting my code and I figured out that I was unintentionally sharing the same instance between different tasks, which resulted in an execution mess... But, fortunately, easy to fix.

Nonetheless I am still wondering if I need to release the memory as I showed in my code, or if that is unnecessary in case I can rely on the java garbage collector.

Thanks again. Fran

ignazio1977 commented 1 year ago

If ontologies and managers are not reused outside of the thread or any returned objects, then there shouldn't be a need to do anything - the garbage collector will collect the instances. Axioms, entities and other elements might still exist in data factory caches, but those are limited in size and will also be emptied if memory is running low (many bugs in that area have been fixed a few years ago).

If you experience situations that look like memory leaks, please raise an issue here - the fact that a number of bugs was fixed does not mean that all bugs were fixed, so please let us know.

fanavarro commented 1 year ago

Perfect, thanks @ignazio1977 !!

I had to use a very old owlapi version previously and I saw some memory issues, but now we have been able to update to the latest version, I will notice if I see something.

Thanks again and have a nice weekend, Fran.