eclipse-sirius / sirius-emf-json

JSON-based EMF Resource implementation - part of Eclipse Sirius
https://eclipse.dev/sirius/sirius-web.html
Eclipse Public License 2.0
5 stars 10 forks source link

PackageNotFoundErrors use significant amount of memory #43

Open pcdavid opened 3 weeks ago

pcdavid commented 3 weeks ago

This might be partially related to the Sirius Web context... but it's the main use case in practice.

40 changed PackageNotFoundException into a plain class to avoid the runtime cost of creating many exceptions. The result is much better in terms of speed, but we still create a lot of instances of this error, most (all?) of them with the exact same data.

After loading the "Sirius Web" Papaya example, the total retained size of all JsonResourceImpl is about 21MB, almost 1/4th of it in 48795 instances of PackageNotFoundError:

image

An analysis of the duplicate strings shows that whenever an inter-resource reference is parsed, because we try to interpret the target resource URI as an EPackage nsURI first, and fail in 99.9% of the cases, we create a new String with the resource URI (all/most of the UUID-like strings in the screenshot below) and wrap it in a new PackageNotFoundError in each case:

image

Possible solutions:

  1. Stop creating these PackageNotFoundError, or at least make this optional.
  2. Clear them after load (on the Sirius Web side), if we do not actually use them for anything.
  3. Deduplicate them.
  4. Stop trying to resolve external resource URIs as EPackage (a very rare case in practice) as the default. From my understanding, for non-null input, GsonEObjectDeserializer.getPackageForURI(String) will always end up calling EMF's URI.createURI(uriString) which itself will end up in org.eclipse.emf.common.util.URI.URIPool.StringAccessUnit.parseIntoURI(String). I think a valid URI will always contain a : scheme separator, but that is never the case for the names/URIs of Sirius Web documents (which use UUIDs), so we could probably bypass the whole getPackageForURI method (and the corresponding errors) when the uriString does not contain : (which should be fast to test).