Skip to content

Memory leaks in Silicon #579

Open
Open
@fpoli

Description

Calling Silicon::verify multiple times (sequentially) on the same verifier instance leaks memory, which is freed only when the verifier is destructed. In other words, there is some state that is not cleaned by Silicon's private reset method. In Prusti, this causes our prusti-server to go OOM after a while when verifying large programs, because we try to reuse the same verifier instance for multiple verification requests.

The memory leak can be debugged in VisualVM by inspecting the diff between heap dumps taken at different times after a manual GC run. To give an example, here is one of the paths from the verifier to one of the leaked viper.silicon.state.terms.Less instances:

this     - value: viper.silicon.state.terms.Less #1
 <- head     - class: scala.collection.immutable.$colon$colon, value: viper.silicon.state.terms.Less #1
  <- equalityDefiningMembers     - class: viper.silicon.state.terms.And, value: scala.collection.immutable.$colon$colon #3843
   <- body     - class: viper.silicon.state.terms.Let, value: viper.silicon.state.terms.And #1
    <- body     - class: viper.silicon.state.terms.Quantification, value: viper.silicon.state.terms.Let #1
     <- [0]     - class: java.lang.Object[], value: viper.silicon.state.terms.Quantification #1
      <- prefix1     - class: scala.collection.immutable.Vector1, value: java.lang.Object[] #6000
       <- postConditionAxioms     - class: viper.silicon.supporters.functions.DefaultFunctionVerificationUnitProvider$functionsSupporter$, value: scala.collection.immutable.Vector1 #16
        <- functionsSupporter$module     - class: viper.silicon.verifier.DefaultMasterVerifier, value: viper.silicon.supporters.functions.DefaultFunctionVerificationUnitProvider$functionsSupporter$ #1
         <- verifier (JNI local)     - class: viper.silicon.Silicon, value: viper.silicon.verifier.DefaultMasterVerifier #1

For this particular instance, it seems that postConditionAxioms in functionsSupporter keeps growing.

Another example, for a viper.silicon.state.terms.Trigger instance:

this     - value: viper.silicon.state.terms.Trigger #5
 <- head     - class: scala.collection.immutable.$colon$colon, value: viper.silicon.state.terms.Trigger #5
  <- triggers     - class: viper.silicon.state.terms.Quantification, value: scala.collection.immutable.$colon$colon #4167
   <- [1]     - class: java.lang.Object[], value: viper.silicon.state.terms.Quantification #5
    <- prefix1     - class: scala.collection.immutable.Vector1, value: java.lang.Object[] #5985
     <- emittedFunctionAxioms     - class: viper.silicon.supporters.functions.DefaultFunctionVerificationUnitProvider$functionsSupporter$, value: scala.collection.immutable.Vector1 #8
      <- head     - class: scala.collection.immutable.$colon$colon, value: viper.silicon.supporters.functions.DefaultFunctionVerificationUnitProvider$functionsSupporter$ #1
       <- next     - class: scala.collection.immutable.$colon$colon, value: scala.collection.immutable.$colon$colon #254
        <- next     - class: scala.collection.immutable.$colon$colon, value: scala.collection.immutable.$colon$colon #253
         <- next     - class: scala.collection.immutable.$colon$colon, value: scala.collection.immutable.$colon$colon #252
          <- next     - class: scala.collection.immutable.$colon$colon, value: scala.collection.immutable.$colon$colon #251
           <- next     - class: scala.collection.immutable.$colon$colon, value: scala.collection.immutable.$colon$colon #250
            <- next     - class: scala.collection.immutable.$colon$colon, value: scala.collection.immutable.$colon$colon #249
             <- next     - class: scala.collection.immutable.$colon$colon, value: scala.collection.immutable.$colon$colon #248
              <- symbolDeclarationOrder     - class: viper.silicon.verifier.DefaultMasterVerifier, value: scala.collection.immutable.$colon$colon #247
               <- verifier (JNI local)     - class: viper.silicon.Silicon, value: viper.silicon.verifier.DefaultMasterVerifier #1

I probably can find many more cases, if I keep looking at the heap dumps.

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions