Java 1.8 and ExtendProperties [message #1744671] |
Thu, 29 September 2016 11:57 |
Sebastian Zitzelsberger Messages: 33 Registered: August 2014 |
Member |
|
|
Hi Epsilon Team,
I am currently evaluating whether i can use epsilon in a java standalone application while using a java 1.8 jdk as a runtime environment.
I found out that everything seems to be working fine, except the extendedProperties.
I am using ExtendProperties rather excessivley ( > 400k set properties in total) and everything is fine while using a 1.7 jdk.
When using java 1.8 however, your Cache implementation in the ExtendedProperties returns wrong properties for certain objects if the number of properties exceeds a certain (unknown) limit.
I have attached a minimal example that shows the effect.
I have a simple model with 300k entities.
Each entity has a single attribute, that is unique accross the model.
I set an extended Property for the first 150k that is a copy of that attribute and perform a check afterwards that prints all entities (within the first 150k) to the console whose extendedProperty value does not equal the attribute value.
The list is empty when using java 1.7 (as expected) but contains 4 entries when using java 1.8.
My first guesses are that something must have changed regarding java garbage collection ( you are using weak references in your Cache implementation) or regarding your hashCode generation ( see your IdentityBasedWeakReference Implementation).
When using my own implementation of your ExtendedProperties class that uses this collection
protected LinkedHashMap<Object, LinkedHashMap<String, Object>> properties = new LinkedHashMap<Object, LinkedHashMap<String, Object>>();
instead of your Cache implementation, i get the correct extended Properties in java 1.7 and java 1.8.
Can you please check the example and explain the use of your Cache Implementation?
Greetings
Sebastian
[Updated on: Thu, 29 September 2016 11:59] Report message to a moderator
|
|
|
Re: Java 1.8 and ExtendProperties [message #1744970 is a reply to message #1744671] |
Mon, 03 October 2016 15:02 |
|
Sorry for the delay: Dimitris and I are currently away on a conference, so we are a bit busy. I have indeed confirmed your issue on my machine with JDK7 and JDK8. It is quite puzzling: we'll be definitely researching this as soon as possible. I have seen a similar problem with this style of cache on other open source systems in JDK8 (e.g. OrientDB).
Essentially, the cache uses weak references so we can reclaim memory as soon as we stop referring to the cached values. The cache uses object identity hashcodes as keys, which we assumed to be unique within a run of the JVM for practical reasons. It feels as if this assumption was no longer 100% true in JDK8: we will have to review this bit and fix the issue once we've found a good fix. Stay tuned .
[Updated on: Mon, 03 October 2016 15:25] Report message to a moderator
|
|
|
|
|
|
|
Re: Java 1.8 and ExtendProperties [message #1745040 is a reply to message #1745020] |
Tue, 04 October 2016 12:24 |
|
You're right: EObject uses the default hashCode, hmm. (We force this anyway because Epsilon with more things than just EMF, anyway.)
It might be because LinkedHashMap uses the hashCode() plus the equals() method: the hashCode is used to go to a bucket and then it loops through the linked elements in the bucket testing with equals. At least, this is what the JDK8 source code suggests:
final Node<K,V> getNode(int hash, Object key) {
Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
if ((tab = table) != null && (n = tab.length) > 0 &&
(first = tab[(n - 1) & hash]) != null) {
if (first.hash == hash && // always check first node
((k = first.key) == key || (key != null && key.equals(k))))
return first;
if ((e = first.next) != null) {
if (first instanceof TreeNode)
return ((TreeNode<K,V>)first).getTreeNode(hash, key);
do {
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e;
} while ((e = e.next) != null);
}
}
return null;
}
So in this case, the issue might have been in our IdentityBasedWeakReference wrapper, which originally implemented equals(...) as hashCode() == other.hashCode(). I'm pretty sure I tried replacing it with direct object comprison and it didn't help, but I'll look again into it. Perhaps the fix was easier than I thought .
As for Epsilon 1.4, it's coming soon: the release review is underway. Hopefully it should be ready within October.
|
|
|
Re: Java 1.8 and ExtendProperties [message #1745042 is a reply to message #1745040] |
Tue, 04 October 2016 12:40 |
|
Well, actually that was the issue (the equals() method of IdentityBasedWeakReference). I have reverted the first fix I tried (which required Guava) and pushed this other fix.
Again, it'll be live in an hour or two: please try it out when you can and re-confirm. Thanks for the helpful discussion .
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.02807 seconds