Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Out of memory exception on OSATE 2.6.0 (testing) #1997

Closed
smithdtyler opened this issue Sep 20, 2019 · 6 comments · Fixed by #2000
Closed

Out of memory exception on OSATE 2.6.0 (testing) #1997

smithdtyler opened this issue Sep 20, 2019 · 6 comments · Fixed by #2000

Comments

@smithdtyler
Copy link

@smithdtyler smithdtyler commented Sep 20, 2019

When running unit tests, we are getting out of memory exceptions on OSATE testing (2.6.0) but not on OSATE stable (2.5.2).

I have encountered a similar error before (#1726) but was unable to replace it using the minimal example used in that issue.

!ENTRY org.eclipse.core.jobs 4 2 2019-09-20 08:39:14.775
!MESSAGE An internal error occurred during: "Building workspace".
!STACK 0
java.lang.OutOfMemoryError: GC overhead limit exceeded
	at org.eclipse.emf.ecore.util.EContentsEList.newResolvingListIterator(EContentsEList.java:89)
	at org.eclipse.emf.ecore.util.EContentsEList.newListIterator(EContentsEList.java:84)
	at org.eclipse.emf.ecore.util.EContentsEList.newIterator(EContentsEList.java:99)
	at org.eclipse.emf.ecore.util.EContentsEList.iterator(EContentsEList.java:151)
	at org.eclipse.emf.ecore.impl.BasicEObjectImpl$2.getChildren(BasicEObjectImpl.java:842)
	at org.eclipse.emf.common.util.AbstractTreeIterator.next(AbstractTreeIterator.java:138)
	at org.eclipse.xtext.EcoreUtil2$1.next(EcoreUtil2.java:249)
	at org.eclipse.xtext.EcoreUtil2$1.next(EcoreUtil2.java:215)
	at org.eclipse.xtext.GrammarUtil.collectAllRules(GrammarUtil.java:406)
	at org.eclipse.xtext.GrammarUtil.allRules(GrammarUtil.java:383)
	at org.eclipse.xtext.GrammarUtil.allTerminalRules(GrammarUtil.java:434)
	at org.eclipse.xtext.conversion.impl.AbstractDeclarativeValueConverterService.registerEFactoryConverters(AbstractDeclarativeValueConverterService.java:212)
	at org.eclipse.xtext.conversion.impl.AbstractDeclarativeValueConverterService.internalRegisterForClass(AbstractDeclarativeValueConverterService.java:115)
	at org.eclipse.xtext.conversion.impl.AbstractDeclarativeValueConverterService.getConverters(AbstractDeclarativeValueConverterService.java:100)
	at org.eclipse.xtext.conversion.impl.AbstractDeclarativeValueConverterService.getConverter(AbstractDeclarativeValueConverterService.java:88)
	at org.eclipse.xtext.conversion.impl.AbstractDeclarativeValueConverterService.toValue(AbstractDeclarativeValueConverterService.java:79)
	at org.eclipse.xtext.linking.impl.LinkingHelper.getCrossRefNodeAsString(LinkingHelper.java:66)
	at org.osate.xtext.aadl2.properties.linking.PropertiesLinkingService.getCrossRefNodeAsString(PropertiesLinkingService.java:191)
	at org.osate.xtext.aadl2.linking.Aadl2LinkingService.getLinkedObjects(Aadl2LinkingService.java:143)
	at org.eclipse.xtext.linking.lazy.LazyLinkingResource.getEObject(LazyLinkingResource.java:265)
	at org.eclipse.xtext.linking.lazy.LazyLinkingResource.getEObject(LazyLinkingResource.java:236)
	at org.eclipse.xtext.resource.persistence.StorageAwareResource.getEObject(StorageAwareResource.java:119)
	at org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.getEObject(ResourceSetImpl.java:223)
	at org.eclipse.emf.ecore.util.EcoreUtil.resolve(EcoreUtil.java:209)
	at org.eclipse.emf.ecore.util.EcoreUtil.resolve(EcoreUtil.java:269)
	at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eResolveProxy(BasicEObjectImpl.java:1477)
	at org.osate.aadl2.impl.SubcomponentImpl.getRefinedElement(SubcomponentImpl.java:784)
	at org.osate.aadl2.impl.RefinableElementImpl.setName(RefinableElementImpl.java:189)
	at org.osate.aadl2.impl.SubcomponentImpl.setRefined(SubcomponentImpl.java:471)
	at org.osate.aadl2.impl.SubcomponentImpl.eSet(SubcomponentImpl.java:587)
	at org.osate.aadl2.impl.SystemSubcomponentImpl.eSet(SystemSubcomponentImpl.java:194)
	at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eSet(BasicEObjectImpl.java:1

Environment

  • OSATE Testing 2.6.0
  • Windows 7
@lwrage
Copy link
Contributor

@lwrage lwrage commented Sep 23, 2019

Do you run the same test every day? When exactly did this start to occur? This information would help help to narrow down which commit may have caused the OOM.

@smithdtyler
Copy link
Author

@smithdtyler smithdtyler commented Sep 24, 2019

Based on a review of a heap dump and recent commits, I suspect ae4d2e1

Screen Shot 2019-09-24 at 12 04 34 PM

Screen Shot 2019-09-24 at 12 06 29 PM

Screen Shot 2019-09-24 at 12 06 49 PM

See ae4d2e1#diff-0846f867f735829d8b3dd091032830da

@smithdtyler
Copy link
Author

@smithdtyler smithdtyler commented Sep 26, 2019

I think the problem is that CacheAdapter.INSTANCE is a static field (and thus not garbage collected)

/**
 * @deprecated
 * @see CacheAdapter#getInstance()
 */
public static final CacheAdapter INSTANCE = createCacheAdapter();

The cache in CacheAdapter is a persistent cache (i.e. not a weak cache)

private final Map<Resource, Map<EObject, Map<Object, Object>>> values = Collections
	.synchronizedMap(this
		.<Resource, Map<EObject, Map<Object, Object>>> createHashMap());

protected <K, V> Map<K, V> createHashMap() {
	return new HashMap<K, V>();
} 

/**
 * @since 1.7
 */
public static CacheAdapter getInstance() {
	return THREAD_LOCAL == null
		? INSTANCE
		: THREAD_LOCAL.get();
}

THREAD_LOCAL is also static:

protected static final ThreadLocal<CacheAdapter> THREAD_LOCAL = System
	.getProperty("org.eclipse.uml2.common.util.CacheAdapter.ThreadLocal") != null //$NON-NLS-1$
	? new ThreadLocal<CacheAdapter>() {

		@Override
		protected CacheAdapter initialValue() {
			return createCacheAdapter();
		}

	}
	: null;

The change in ae4d2e1 (such as that shown below) switches from using the getCacheAdapter() method to the getInstance() method:

Screen Shot 2019-09-26 at 9 09 52 AM

The former method avoids the static INSTANCE field.

public static CacheAdapter getCacheAdapter(Notifier notifier) {
	List<Adapter> eAdapters = notifier.eAdapters();

	for (int i = 0, size = eAdapters.size(); i < size; i++) {
		Object adapter = eAdapters.get(i);

		if (adapter instanceof CacheAdapter) {
			return (CacheAdapter) adapter;
		}
	}

	return null;
}

@reteprelief, why did you switch to CacheAdapter.getInstance()?

@lwrage
Copy link
Contributor

@lwrage lwrage commented Sep 26, 2019

That code is generated by the eclipse UML code generator. The code generator behaves differently now. We can try to switch back to the old implementation.

@lwrage
Copy link
Contributor

@lwrage lwrage commented Sep 26, 2019

We can also turn off the caching completely.

@smithdtyler
Copy link
Author

@smithdtyler smithdtyler commented Sep 26, 2019

We can also turn off the caching completely.

I don't know enough about what we gain through caching to make a recommendation here. I don't think either option significantly affects my use case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants