Skip to content

Commit

Permalink
Reenable LiveVersionMapTests.testRamBytesUsed on Java 9. (#29063)
Browse files Browse the repository at this point in the history
I also had to make the test more lenient. This is due to the fact that
Lucene's RamUsageTester was changed in order not to reflect `java.*`
classes and the way that it estimates ram usage of maps is by assuming
it has similar memory usage to an `Object[]` array that stores all keys
and values. The implementation in `LiveVersionMap` tries to be slightly
more realistic by taking the load factor and linked lists into account,
so it usually gives a higher estimate which happens to be closer to
reality.

Closes #22548
  • Loading branch information
jpountz authored Mar 15, 2018
1 parent 8593316 commit 18d848f
Showing 1 changed file with 18 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,9 @@

import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.BytesRefBuilder;
import org.apache.lucene.util.Constants;
import org.apache.lucene.util.RamUsageTester;
import org.apache.lucene.util.TestUtil;
import org.elasticsearch.Assertions;
import org.elasticsearch.bootstrap.JavaVersion;
import org.elasticsearch.common.lease.Releasable;
import org.elasticsearch.test.ESTestCase;

Expand All @@ -43,7 +42,6 @@
public class LiveVersionMapTests extends ESTestCase {

public void testRamBytesUsed() throws Exception {
assumeTrue("Test disabled for JDK 9", JavaVersion.current().compareTo(JavaVersion.parse("9")) < 0);
LiveVersionMap map = new LiveVersionMap();
for (int i = 0; i < 100000; ++i) {
BytesRefBuilder uid = new BytesRefBuilder();
Expand Down Expand Up @@ -72,8 +70,23 @@ public void testRamBytesUsed() throws Exception {
}
actualRamBytesUsed = RamUsageTester.sizeOf(map);
estimatedRamBytesUsed = map.ramBytesUsed();
// less than 25% off
assertEquals(actualRamBytesUsed, estimatedRamBytesUsed, actualRamBytesUsed / 4);
long tolerance;
if (Constants.JRE_IS_MINIMUM_JAVA9) {
// With Java 9, RamUsageTester computes the memory usage of maps as
// the memory usage of an array that would contain exactly all keys
// and values. This is an under-estimation of the actual memory
// usage since it ignores the impact of the load factor and of the
// linked list/tree that is used to resolve collisions. So we use a
// bigger tolerance.
// less than 50% off
tolerance = actualRamBytesUsed / 2;
} else {
// Java 8 is more accurate by doing reflection into the actual JDK classes
// so we give it a lower error bound.
// less than 25% off
tolerance = actualRamBytesUsed / 4;
}
assertEquals(actualRamBytesUsed, estimatedRamBytesUsed, tolerance);
}

private BytesRef uid(String string) {
Expand Down

0 comments on commit 18d848f

Please sign in to comment.