package rocks.inspectit.server.cache.impl;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.is;
import java.lang.reflect.Field;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Stack;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.log4j.Logger;
import org.cliffc.high_scale_lib.NonBlockingHashMapLong;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import com.javamex.classmexer.MemoryUtil;
import com.javamex.classmexer.MemoryUtil.VisibilityFilter;
import rocks.inspectit.server.cache.AbstractObjectSizes;
import rocks.inspectit.server.test.AbstractTestNGLogSupport;
import rocks.inspectit.shared.all.cmr.cache.IObjectSizes;
import rocks.inspectit.shared.all.communication.DefaultData;
import rocks.inspectit.shared.all.communication.MethodSensorData;
import rocks.inspectit.shared.all.communication.Sizeable;
import rocks.inspectit.shared.all.communication.data.AggregatedExceptionSensorData;
import rocks.inspectit.shared.all.communication.data.AggregatedHttpTimerData;
import rocks.inspectit.shared.all.communication.data.AggregatedSqlStatementData;
import rocks.inspectit.shared.all.communication.data.AggregatedTimerData;
import rocks.inspectit.shared.all.communication.data.ClassLoadingInformationData;
import rocks.inspectit.shared.all.communication.data.CompilationInformationData;
import rocks.inspectit.shared.all.communication.data.ExceptionSensorData;
import rocks.inspectit.shared.all.communication.data.HttpTimerData;
import rocks.inspectit.shared.all.communication.data.InvocationAwareData;
import rocks.inspectit.shared.all.communication.data.InvocationSequenceData;
import rocks.inspectit.shared.all.communication.data.MemoryInformationData;
import rocks.inspectit.shared.all.communication.data.RuntimeInformationData;
import rocks.inspectit.shared.all.communication.data.SqlStatementData;
import rocks.inspectit.shared.all.communication.data.SystemInformationData;
import rocks.inspectit.shared.all.communication.data.ThreadInformationData;
import rocks.inspectit.shared.all.communication.data.TimerData;
import rocks.inspectit.shared.all.tracing.data.ClientSpan;
import rocks.inspectit.shared.all.tracing.data.ServerSpan;
import rocks.inspectit.shared.all.util.UnderlyingSystemInfo;
import rocks.inspectit.shared.all.util.UnderlyingSystemInfo.JvmProvider;
/**
* This test class provides test for the method of {@link IObjectSizes} that calculate the size of
* the core Java classes.
*
* @author Ivan Senic
*
*/
@SuppressWarnings("PMD")
public class MemoryCalculationTest extends AbstractTestNGLogSupport {
/**
* The logger of this class.
*/
private static final Logger LOGGER = Logger.getLogger(MemoryCalculationTest.class);
/**
* Our classes to be tested.
*/
public static final Object[][] TESTING_CLASSES = new Object[][] { { TestDefaultData.class }, { TestMethodSensorData.class }, { TestInvocationAwareData.class }, { TimerData.class },
{ SqlStatementData.class }, { ExceptionSensorData.class }, { InvocationSequenceData.class }, { ClassLoadingInformationData.class }, { CompilationInformationData.class },
{ MemoryInformationData.class }, { RuntimeInformationData.class }, { SystemInformationData.class }, { ThreadInformationData.class }, { HttpTimerData.class },
{ AggregatedExceptionSensorData.class }, { AggregatedHttpTimerData.class }, { AggregatedSqlStatementData.class }, { AggregatedTimerData.class }, { ClientSpan.class },
{ ServerSpan.class } };
/**
* Amount that we add to each hash map because of the entry, key and value set safety.
*/
private static long HASH_MAP_SAFTY_DELTA;
/**
* Field for knowing how much big is the hash map table.
*/
private static Field oracleHashMapTable;
/**
* Field for knowing how much big is the hash map table.
*/
private static Field ibmHashMapTable;
/**
* {@link IObjectSizes}.
*/
private IObjectSizes objectSizes;
/**
* Gets the proper instance of the {@link IObjectSizes} because it s dependent on the system
* test is run on.
*
* @throws Exception
* If Exception occurs.
*/
@BeforeClass
public void initCorrectObjectSizesInstance() throws Exception {
objectSizes = new ObjectSizesFactory().getObject();
if ((UnderlyingSystemInfo.JVM_PROVIDER == JvmProvider.SUN) || (UnderlyingSystemInfo.JVM_PROVIDER == JvmProvider.ORACLE)) {
oracleHashMapTable = HashMap.class.getDeclaredField("table"); // NOPMD
if (null != oracleHashMapTable) {
oracleHashMapTable.setAccessible(true);
}
} else if (UnderlyingSystemInfo.JVM_PROVIDER == JvmProvider.IBM) {
ibmHashMapTable = HashMap.class.getDeclaredField("table"); // NOPMD
if (null != ibmHashMapTable) {
ibmHashMapTable.setAccessible(true);
}
}
HASH_MAP_SAFTY_DELTA = objectSizes.getSizeOfHashMapKeyEntrySet();
}
/**
* Tests size of a simple {@link Object}.
*/
@Test
public void object() {
Object o = new Object();
long ourSize = objectSizes.getSizeOfObjectObject();
long theirSize = MemoryUtil.deepMemoryUsageOf(o, VisibilityFilter.ALL);
assertThat(ourSize, is(equalTo(theirSize)));
}
/**
* Tests size of a {@link Long}.
*/
@Test
public void longObject() {
Long l = Long.valueOf(1);
long ourSize = objectSizes.getSizeOfLongObject();
long theirSize = MemoryUtil.deepMemoryUsageOf(l, VisibilityFilter.ALL);
assertThat(ourSize, is(equalTo(theirSize)));
}
/**
* Tests size of a {@link Integer}.
*/
@Test
public void integerObject() {
Integer i = Integer.valueOf(1);
long ourSize = objectSizes.getSizeOfIntegerObject();
long theirSize = MemoryUtil.deepMemoryUsageOf(i, VisibilityFilter.ALL);
assertThat(ourSize, is(equalTo(theirSize)));
}
/**
* Tests size of a {@link Short}.
*/
@Test
public void shortObject() {
Short s = Short.valueOf((short) 1); // NOPMD
long ourSize = objectSizes.getSizeOfShortObject();
long theirSize = MemoryUtil.deepMemoryUsageOf(s, VisibilityFilter.ALL);
assertThat(ourSize, is(equalTo(theirSize)));
}
/**
* Tests size of a {@link Character}.
*/
@Test
public void characterObject() {
Character s = Character.valueOf('c');
long ourSize = objectSizes.getSizeOfCharacterObject();
long theirSize = MemoryUtil.deepMemoryUsageOf(s, VisibilityFilter.ALL);
assertThat(ourSize, is(equalTo(theirSize)));
}
/**
* Tests size of a {@link Boolean}.
*/
@Test
public void booleanObject() {
Boolean b = Boolean.TRUE;
long ourSize = objectSizes.getSizeOfBooleanObject();
long theirSize = MemoryUtil.deepMemoryUsageOf(b, VisibilityFilter.ALL);
assertThat(ourSize, is(equalTo(theirSize)));
}
/**
* Tests empty{@link String}.
*/
@Test(invocationCount = 50)
public void empryString() {
String s = "";
long ourSize = objectSizes.getSizeOf(s);
long theirSize = MemoryUtil.deepMemoryUsageOf(s, VisibilityFilter.ALL);
assertThat(ourSize, is(equalTo(theirSize)));
}
/**
* Tests size of a random {@link String} with length from 1 - 100 characters.
*/
@Test(invocationCount = 50)
public void string() {
int size = (int) (Math.random() * 100);
String s = RandomStringUtils.random(size);
long ourSize = objectSizes.getSizeOf(s);
long theirSize = MemoryUtil.deepMemoryUsageOf(s, VisibilityFilter.ALL);
assertThat(ourSize, is(equalTo(theirSize)));
}
/**
* Tests size of a {@link Timestamp}.
*/
@Test
public void timestamp() {
Timestamp t = new Timestamp(new Date().getTime());
long ourSize = objectSizes.getSizeOf(t);
long theirSize = MemoryUtil.deepMemoryUsageOf(t, VisibilityFilter.ALL);
assertThat(ourSize, is(equalTo(theirSize)));
}
/**
* Test the array of size 0 and 1.
*/
@Test
public void emptyArray() {
Object[] array = new Object[0];
long ourSize = objectSizes.getSizeOfArray(array.length);
long theirSize = MemoryUtil.deepMemoryUsageOf(array, VisibilityFilter.ALL);
assertThat(ourSize, is(equalTo(theirSize)));
array = new Object[1];
ourSize = objectSizes.getSizeOfArray(array.length);
theirSize = MemoryUtil.deepMemoryUsageOf(array, VisibilityFilter.ALL);
assertThat(ourSize, is(equalTo(theirSize)));
}
/**
* General test for arrays of different sizes.
*/
@Test(invocationCount = 50)
public void array() {
Object[] array = new Object[(int) (Math.random() * 100)];
long ourSize = objectSizes.getSizeOfArray(array.length);
long theirSize = MemoryUtil.deepMemoryUsageOf(array, VisibilityFilter.ALL);
assertThat("Empty array", ourSize, is(equalTo(theirSize)));
for (int i = 0; i < array.length; i++) {
array[i] = new Object();
}
if (checkObjectGraphIdentityHashCodeCollision(array, new HashSet<Integer>(), new ArrayList<Integer>())) {
LOGGER.info("Object graph identity collision check passed for test: array()");
ourSize = objectSizes.getSizeOfArray(array.length) + (array.length * objectSizes.getSizeOfObjectObject());
theirSize = MemoryUtil.deepMemoryUsageOf(array, VisibilityFilter.ALL);
assertThat("Full array of " + array.length + " elements", ourSize, is(equalTo(theirSize)));
}
}
/**
* boolean array.
*/
@Test(invocationCount = 10)
public void booleanArray() {
boolean[] array = new boolean[(int) (Math.random() * 100)];
long ourSize = objectSizes.getSizeOfPrimitiveArray(array.length, AbstractObjectSizes.BOOLEAN_SIZE);
long theirSize = MemoryUtil.deepMemoryUsageOf(array, VisibilityFilter.ALL);
assertThat("boolean array", ourSize, is(equalTo(theirSize)));
}
/**
* char array.
*/
@Test(invocationCount = 10)
public void charArray() {
char[] array = new char[(int) (Math.random() * 100)];
long ourSize = objectSizes.getSizeOfPrimitiveArray(array.length, AbstractObjectSizes.CHAR_SIZE);
long theirSize = MemoryUtil.deepMemoryUsageOf(array, VisibilityFilter.ALL);
assertThat("char array", ourSize, is(equalTo(theirSize)));
}
/**
* int array.
*/
@Test(invocationCount = 10)
public void intArray() {
int[] array = new int[(int) (Math.random() * 100)];
long ourSize = objectSizes.getSizeOfPrimitiveArray(array.length, AbstractObjectSizes.INT_SIZE);
long theirSize = MemoryUtil.deepMemoryUsageOf(array, VisibilityFilter.ALL);
assertThat("int array", ourSize, is(equalTo(theirSize)));
}
/**
* float array.
*/
@Test(invocationCount = 10)
public void floatArray() {
float[] array = new float[(int) (Math.random() * 100)];
long ourSize = objectSizes.getSizeOfPrimitiveArray(array.length, AbstractObjectSizes.FLOAT_SIZE);
long theirSize = MemoryUtil.deepMemoryUsageOf(array, VisibilityFilter.ALL);
assertThat("float array", ourSize, is(equalTo(theirSize)));
}
/**
* long array.
*/
@Test(invocationCount = 10)
public void longArray() {
long[] array = new long[(int) (Math.random() * 100)];
long ourSize = objectSizes.getSizeOfPrimitiveArray(array.length, AbstractObjectSizes.LONG_SIZE);
long theirSize = MemoryUtil.deepMemoryUsageOf(array, VisibilityFilter.ALL);
assertThat("long array", ourSize, is(equalTo(theirSize)));
}
/**
* double array.
*/
@Test(invocationCount = 10)
public void doubleArray() {
double[] array = new double[(int) (Math.random() * 100)];
long ourSize = objectSizes.getSizeOfPrimitiveArray(array.length, AbstractObjectSizes.DOUBLE_SIZE);
long theirSize = MemoryUtil.deepMemoryUsageOf(array, VisibilityFilter.ALL);
assertThat("double array", ourSize, is(equalTo(theirSize)));
}
/**
* short array.
*/
@Test(invocationCount = 10)
public void shortArray() {
short[] array = new short[(int) (Math.random() * 100)];
long ourSize = objectSizes.getSizeOfPrimitiveArray(array.length, AbstractObjectSizes.SHORT_SIZE);
long theirSize = MemoryUtil.deepMemoryUsageOf(array, VisibilityFilter.ALL);
assertThat("short array", ourSize, is(equalTo(theirSize)));
}
/**
* Tests size of empty and populated {@link ArrayList} object.
*/
@Test(invocationCount = 50)
public void arrayList() {
ArrayList<Object> arrayList = new ArrayList<>();
long ourSize = objectSizes.getSizeOf(arrayList);
long theirSize = MemoryUtil.deepMemoryUsageOf(arrayList, VisibilityFilter.ALL);
assertThat("Empty list", ourSize, is(equalTo(theirSize)));
int size = (int) (Math.random() * 100);
for (int i = 0; i < size; i++) {
arrayList.add(new Object());
}
if (checkObjectGraphIdentityHashCodeCollision(arrayList, new HashSet<Integer>(), new ArrayList<Integer>())) {
LOGGER.info("Object graph identity collision check passed for test: arrayList()");
ourSize = objectSizes.getSizeOf(arrayList) + (size * objectSizes.getSizeOfObjectObject());
theirSize = MemoryUtil.deepMemoryUsageOf(arrayList, VisibilityFilter.ALL);
assertThat("Random list size", ourSize, is(equalTo(theirSize)));
}
}
/**
* Tests size of empty and populated {@link ArrayList} object with initial size of 0.
*/
@Test(invocationCount = 50)
public void arrayListInitializeZero() {
ArrayList<Object> arrayList = new ArrayList<>(0);
long ourSize = objectSizes.getSizeOf(arrayList, 0);
long theirSize = MemoryUtil.deepMemoryUsageOf(arrayList, VisibilityFilter.ALL);
assertThat("Empty list", ourSize, is(equalTo(theirSize)));
int size = (int) (Math.random() * 100);
for (int i = 0; i < size; i++) {
arrayList.add(new Object());
}
if (checkObjectGraphIdentityHashCodeCollision(arrayList, new HashSet<Integer>(), new ArrayList<Integer>())) {
LOGGER.info("Object graph identity collision check passed for test: arrayListInitializeZero()");
ourSize = objectSizes.getSizeOf(arrayList, 0) + (size * objectSizes.getSizeOfObjectObject());
theirSize = MemoryUtil.deepMemoryUsageOf(arrayList, VisibilityFilter.ALL);
assertThat("Random list size", ourSize, is(equalTo(theirSize)));
}
}
/**
* Tests size of empty and populated {@link HashMap} object.
*
* @throws IllegalAccessException
* @throws IllegalArgumentException
*/
@Test(invocationCount = 50)
public void hashMap() throws IllegalArgumentException, IllegalAccessException {
HashMap<Object, Object> hashMap = new HashMap<>();
long ourSize = objectSizes.getSizeOfHashMap(0);
long theirSize = MemoryUtil.deepMemoryUsageOf(hashMap, VisibilityFilter.ALL);
assertThat("Empty map", ourSize, is(equalTo(theirSize + HASH_MAP_SAFTY_DELTA)));
int size = (int) (Math.random() * 100);
for (int i = 0; i < size; i++) {
hashMap.put(new Object(), new Object());
}
if (checkObjectGraphIdentityHashCodeCollision(hashMap, new HashSet<Integer>(), new ArrayList<Integer>())) {
LOGGER.info("Object graph identity collision check passed for test: hashMap()");
ourSize = objectSizes.getSizeOfHashMap(hashMap.size()) + (2 * size * objectSizes.getSizeOfObjectObject());
theirSize = MemoryUtil.deepMemoryUsageOf(hashMap, VisibilityFilter.ALL);
boolean tableCorrect = false;
Object[] table = null;
if (null != oracleHashMapTable) {
table = (Object[]) oracleHashMapTable.get(hashMap);
} else if (null != ibmHashMapTable) {
table = (Object[]) ibmHashMapTable.get(hashMap);
}
if (null != table) {
int tableSize = table.length;
int ourTableSize = ((AbstractObjectSizes) objectSizes).getHashMapCapacityFromSize(size, 16);
tableCorrect = tableSize == ourTableSize;
}
if (tableCorrect) {
assertThat("Random map size of " + size, ourSize, is(equalTo(theirSize + HASH_MAP_SAFTY_DELTA)));
} else {
assertThat("Random map size of " + size, ourSize, is(greaterThanOrEqualTo(theirSize + HASH_MAP_SAFTY_DELTA)));
}
}
}
/**
* Tests size of empty and populated {@link HashSet} object.
*/
@Test
public void hashSet() {
HashSet<Object> hashSet = new HashSet<>();
long ourSize = objectSizes.getSizeOfHashSet(hashSet.size());
long theirSize = MemoryUtil.deepMemoryUsageOf(hashSet, VisibilityFilter.ALL);
assertThat("Empty set", ourSize, is(equalTo(theirSize + HASH_MAP_SAFTY_DELTA)));
// no hashSet can pass checkObjectGraphIdentityHashCodeCollision check, so we don't checks
// with elements
// since it is anyway holding just the HashMap, testing HashMap will be enough
}
/**
* Tests size of empty and populated {@link ConcurrentHashMap} object. Note that populated
* {@link ConcurrentHashMap} is being tested with only 1 segment. It is impossible to provide
* the correct size with more segments, because it is unknown what will be the distributon of
* elements between segments.
*/
@Test(invocationCount = 50)
public void concurrentHashMap() {
// we can only precisely calculate random amount of elements with one segment
int concurrencyLevel = 1;
ConcurrentHashMap<Object, Object> concurrentHashMap = new ConcurrentHashMap<>(16, 0.75f, concurrencyLevel);
long theirSize = MemoryUtil.deepMemoryUsageOf(concurrentHashMap, VisibilityFilter.ALL);
long ourSize = objectSizes.getSizeOfConcurrentHashMap(0, concurrencyLevel);
assertThat("Empty map", ourSize, is(equalTo(theirSize)));
concurrentHashMap = new ConcurrentHashMap<>(16, 0.75f, 1);
int size = (int) (Math.random() * 100);
for (int i = 0; i < size; i++) {
concurrentHashMap.put(new Object(), new Object());
}
if (checkObjectGraphIdentityHashCodeCollision(concurrentHashMap, new HashSet<Integer>(), new ArrayList<Integer>())) {
LOGGER.info("Object graph identity collision check passed for test: concurrentHashMap()");
theirSize = MemoryUtil.deepMemoryUsageOf(concurrentHashMap, VisibilityFilter.ALL);
ourSize = objectSizes.getSizeOfConcurrentHashMap(size, 1) + (size * 2 * objectSizes.getSizeOfObjectObject());
assertThat("Random map size of " + size, ourSize, is(equalTo(theirSize)));
}
}
/**
* Tests size of empty and populated {@link NonBlockingHashMapLong} object.
*/
@Test(invocationCount = 50)
public void nonBlockingHashMapLong() {
// we can only precisely calculate random amount of elements with one segment
NonBlockingHashMapLong<Object> nonBlockingHashMapLong = new NonBlockingHashMapLong<>();
long theirSize = MemoryUtil.deepMemoryUsageOf(nonBlockingHashMapLong, VisibilityFilter.ALL);
long ourSize = objectSizes.getSizeOfNonBlockingHashMapLong(0);
assertThat("Empty map", ourSize, is(equalTo(theirSize)));
nonBlockingHashMapLong = new NonBlockingHashMapLong<>();
int size = (int) (Math.random() * 100);
for (long l = 1; l <= size; l++) { // zero key not supported
nonBlockingHashMapLong.put(l, Long.valueOf(l));
}
theirSize = MemoryUtil.deepMemoryUsageOf(nonBlockingHashMapLong, VisibilityFilter.ALL);
ourSize = objectSizes.getSizeOfNonBlockingHashMapLong(size) + (size * objectSizes.getSizeOfLongObject());
assertThat("Random map size of " + size, ourSize, is(equalTo(theirSize)));
}
/**
* Tests the arbitrary class created for test purposes.
*/
@Test
public void arbitraryClass() {
TestClass testObject = new TestClass();
long ourSize = objectSizes.getSizeOf(testObject);
long theirSize = MemoryUtil.deepMemoryUsageOf(testObject, VisibilityFilter.ALL);
assertThat("Test class", ourSize, is(equalTo(theirSize)));
}
/**
* Tests the special boolean test class to assuer boolean sizes in JVM are in fact compiled as
* int.
*/
@Test
public void booleanTestClass() {
BooleanTestClass testObject = new BooleanTestClass();
long ourSize = objectSizes.getSizeOf(testObject);
long theirSize = MemoryUtil.deepMemoryUsageOf(testObject, VisibilityFilter.ALL);
assertThat("Boolean test class", ourSize, is(equalTo(theirSize)));
}
/**
* Tests the inspectIT classes instances created by reflection.
* <p>
* <b>Important:</b> The {@link SqlStatementData} class has a problem with calculation when Sun
* JVM is used. The 8 bytes are calculated more than needed. Thus, we need to have the "closeTo"
* assertion until this problem is fixed. This problem is now part of the
* <a href="https://jira.novatec-gmbh.de/browse/INSPECTIT-705">INSPECTIT-705</a> ticket.
*
* @param defaultDataClass
* Class to test.
* @throws InstantiationException
* If {@link InstantiationException} occurs.
* @throws IllegalAccessException
* If {@link IllegalAccessException} occurs.
*/
@Test(dataProvider = "classProvider")
public void inspectitClasses(Class<? extends DefaultData> defaultDataClass) throws InstantiationException, IllegalAccessException {
DefaultData object = defaultDataClass.newInstance();
long ourSize = objectSizes.getSizeOf(object);
long theirSize = MemoryUtil.deepMemoryUsageOf(object, VisibilityFilter.ALL);
assertThat("Size of " + defaultDataClass.getName(), ourSize, is(theirSize));
LOGGER.info("Tested class " + defaultDataClass.getName() + " -> our size: " + ourSize + ", their size: " + theirSize);
}
/**
* Checks for the possible object graph identity hash code collision. Objects that don't pass
* this check can not be given to the classmexer for size calculations, because correct size
* will not be calculated due to the collision that will occur in the classmexer internally.
* <p>
* Most of this method is copied by the classmexer.
*
* @param obj
* Object to check. Note that this method is recursive.
* @param counted
* HashSet that will serve as the collision tester
* @param countedList
* List that will hold all the original identity values.
*
* @return True if there is no collisions in the hash set (map) and object can be tested via
* classmexer. False otherwise.
* @throws SecurityException
*/
private static boolean checkObjectGraphIdentityHashCodeCollision(Object obj, Set<Integer> counted, List<Integer> countedList) throws SecurityException {
Stack<Object> stack = new Stack<>();
stack.push(obj);
while (!(stack.isEmpty())) {
Object object = stack.pop();
Integer identityHashCode = Integer.valueOf(System.identityHashCode(object));
boolean added = counted.add(identityHashCode);
if (!added) {
if (!countedList.contains(identityHashCode)) {
return false;
}
} else {
Class<?> clazz = object.getClass();
Class<?> compType = clazz.getComponentType();
if ((compType != null) && (!(compType.isPrimitive()))) {
Object[] array = (Object[]) object;
for (Object element : array) {
if (element != null) {
stack.push(element);
}
}
}
while (clazz != null) {
for (Field field : clazz.getDeclaredFields()) {
int mod = field.getModifiers();
if ((mod & 0x8) == 0) {
Class<?> fieldClass = field.getType();
if (!(fieldClass.isPrimitive())) {
if (!(field.isAccessible())) {
field.setAccessible(true);
}
try {
Object subObject = field.get(object);
if (subObject != null) {
stack.push(subObject);
}
} catch (IllegalAccessException illAcc) {
throw new InternalError("Couldn't read " + field);
}
}
}
}
clazz = clazz.getSuperclass();
}
}
}
return true;
}
/**
* Provides classes to be tested.
*
* @return Provides classes to be tested.
*/
@DataProvider(name = "classProvider")
public Object[][] classprovider() {
return TESTING_CLASSES; // NOPMD
}
@SuppressWarnings("unused")
private static class TestClass implements Sizeable {
private boolean booleanField;
private int intField;
private long longField;
private String str = RandomStringUtils.random((int) (Math.random() * 100));
@Override
public long getObjectSize(IObjectSizes objectSizes) {
long size = objectSizes.getSizeOfObjectHeader();
size += objectSizes.getPrimitiveTypesSize(1, 1, 1, 0, 1, 0);
size += objectSizes.getSizeOf(str);
return objectSizes.alignTo8Bytes(size);
}
/**
* {@inheritDoc}
*/
@Override
public long getObjectSize(IObjectSizes objectSizes, boolean doAlign) {
return getObjectSize(objectSizes);
}
}
@SuppressWarnings("unused")
private static class BooleanTestClass implements Sizeable {
private boolean b1, b2, b3, b4, b5, b6, b7, b8, b9;
@Override
public long getObjectSize(IObjectSizes objectSizes) {
long size = objectSizes.getSizeOfObjectHeader();
size += objectSizes.getPrimitiveTypesSize(0, 9, 0, 0, 0, 0);
return objectSizes.alignTo8Bytes(size);
}
/**
* {@inheritDoc}
*/
@Override
public long getObjectSize(IObjectSizes objectSizes, boolean doAlign) {
return getObjectSize(objectSizes);
}
}
@SuppressWarnings("serial")
public static class TestDefaultData extends DefaultData {
/**
*
*/
private static final long serialVersionUID = 3932234756253648125L;
};
@SuppressWarnings("serial")
public static class TestMethodSensorData extends MethodSensorData {
/**
*
*/
private static final long serialVersionUID = 2441882106486338907L;
};
@SuppressWarnings("serial")
public static class TestInvocationAwareData extends InvocationAwareData {
/**
*
*/
private static final long serialVersionUID = -1271456832991723364L;
@Override
public double getInvocationAffiliationPercentage() {
return 0;
}
};
}