src/main/java/org/ehcache/sizeof/impl/ReflectionSizeOf.java
@Override
    public long sizeOf(Object obj) {
        if (obj == null) {
            return 0;
        }

        Class<?> aClass = obj.getClass();
        if (aClass.isArray()) {
            return guessArraySize(obj);
        } else {
            long size = CURRENT_JVM_INFORMATION.getObjectHeaderSize();

            Deque<Class<?>> classStack = new ArrayDeque<>();
            for (Class<?> klazz = aClass; klazz != null; klazz = klazz.getSuperclass()) {
                classStack.push(klazz);
            }

            while (!classStack.isEmpty()) {
                Class<?> klazz = classStack.pop();

                //assuming default class layout
                int oops = 0;
                int doubles = 0;
                int words = 0;
                int shorts = 0;
                int bytes = 0;
                for (Field f : klazz.getDeclaredFields()) {
                    if (Modifier.isStatic(f.getModifiers())) {
                        continue;
                    }
                    if (f.getType().isPrimitive()) {
                        switch (PrimitiveType.forType(f.getType())) {
                            case BOOLEAN:
                            case BYTE:
                                bytes++;
                                break;
                            case SHORT:
                            case CHAR:
                                shorts++;
                                break;
                            case INT:
                            case FLOAT:
                                words++;
                                break;
                            case DOUBLE:
                            case LONG:
                                doubles++;
                                break;
                            default:
                                throw new AssertionError();
                        }
                    } else {
                        oops++;
                    }
                }
                if (doubles > 0 && (size % PrimitiveType.LONG.getSize()) != 0) {
                    long length = PrimitiveType.LONG.getSize() - (size % PrimitiveType.LONG.getSize());
                    size += PrimitiveType.LONG.getSize() - (size % PrimitiveType.LONG.getSize());

                    while (length >= PrimitiveType.INT.getSize() && words > 0) {
                        length -= PrimitiveType.INT.getSize();
                        words--;
                    }
                    while (length >= PrimitiveType.SHORT.getSize() && shorts > 0) {
                        length -= PrimitiveType.SHORT.getSize();
                        shorts--;
                    }
                    while (length >= PrimitiveType.BYTE.getSize() && bytes > 0) {
                        length -= PrimitiveType.BYTE.getSize();
                        bytes--;
                    }
                    while (length >= PrimitiveType.getReferenceSize() && oops > 0) {
                        length -= PrimitiveType.getReferenceSize();
                        oops--;
                    }
                }
                size += PrimitiveType.DOUBLE.getSize() * doubles;
                size += PrimitiveType.INT.getSize() * words;
                size += PrimitiveType.SHORT.getSize() * shorts;
                size += PrimitiveType.BYTE.getSize() * bytes;

                if (oops > 0) {
                    if ((size % PrimitiveType.getReferenceSize()) != 0) {
                        size += PrimitiveType.getReferenceSize() - (size % PrimitiveType.getReferenceSize());
                    }
                    size += oops * PrimitiveType.getReferenceSize();
                }

                if ((doubles + words + shorts + bytes + oops) > 0 && (size % PrimitiveType.getReferenceSize()) != 0) {
                    size += PrimitiveType.getReferenceSize() - (size % PrimitiveType.getReferenceSize());
                }
            }
            if ((size % CURRENT_JVM_INFORMATION.getObjectAlignment()) != 0) {
                size += CURRENT_JVM_INFORMATION.getObjectAlignment() - (size % CURRENT_JVM_INFORMATION.getObjectAlignment());
            }
            return Math.max(size, CURRENT_JVM_INFORMATION.getMinimumObjectSize());
        }
    }
@Override
    public long sizeOf(Object obj) {
        if (obj == null) {
            return 0;
        }

        Class<?> aClass = obj.getClass();
        if (aClass.isArray()) {
            return guessArraySize(obj);
        } else {
            long size = CURRENT_JVM_INFORMATION.getObjectHeaderSize();

            Deque<Class<?>> classStack = new ArrayDeque<>();
            for (Class<?> klazz = aClass; klazz != null; klazz = klazz.getSuperclass()) {
                classStack.push(klazz);
            }

            while (!classStack.isEmpty()) {
                Class<?> klazz = classStack.pop();

                //assuming default class layout
                int oops = 0;
                int doubles = 0;
                int words = 0;
                int shorts = 0;
                int bytes = 0;
                for (Field f : klazz.getDeclaredFields()) {
                    if (Modifier.isStatic(f.getModifiers())) {
                        continue;
                    }
                    if (f.getType().isPrimitive()) {
                        switch (PrimitiveType.forType(f.getType())) {
                            case BOOLEAN:
                            case BYTE:
                                bytes++;
                                break;
                            case SHORT:
                            case CHAR:
                                shorts++;
                                break;
                            case INT:
                            case FLOAT:
                                words++;
                                break;
                            case DOUBLE:
                            case LONG:
                                doubles++;
                                break;
                            default:
                                throw new AssertionError();
                        }
                    } else {
                        oops++;
                    }
                }
                if (doubles > 0 && (size % PrimitiveType.LONG.getSize()) != 0) {
                    long length = PrimitiveType.LONG.getSize() - (size % PrimitiveType.LONG.getSize());
                    size += PrimitiveType.LONG.getSize() - (size % PrimitiveType.LONG.getSize());

                    while (length >= PrimitiveType.INT.getSize() && words > 0) {
                        length -= PrimitiveType.INT.getSize();
                        words--;
                    }
                    while (length >= PrimitiveType.SHORT.getSize() && shorts > 0) {
                        length -= PrimitiveType.SHORT.getSize();
                        shorts--;
                    }
                    while (length >= PrimitiveType.BYTE.getSize() && bytes > 0) {
                        length -= PrimitiveType.BYTE.getSize();
                        bytes--;
                    }
                    while (length >= PrimitiveType.getReferenceSize() && oops > 0) {
                        length -= PrimitiveType.getReferenceSize();
                        oops--;
                    }
                }
                size += PrimitiveType.DOUBLE.getSize() * doubles;
                size += PrimitiveType.INT.getSize() * words;
                size += PrimitiveType.SHORT.getSize() * shorts;
                size += PrimitiveType.BYTE.getSize() * bytes;

                if (oops > 0) {
                    if ((size % PrimitiveType.getReferenceSize()) != 0) {
                        size += PrimitiveType.getReferenceSize() - (size % PrimitiveType.getReferenceSize());
                    }
                    size += oops * PrimitiveType.getReferenceSize();
                }

                if ((doubles + words + shorts + bytes + oops) > 0 && (size % PrimitiveType.getReferenceSize()) != 0) {
                    size += PrimitiveType.getReferenceSize() - (size % PrimitiveType.getReferenceSize());
                }
            }
            if ((size % CURRENT_JVM_INFORMATION.getObjectAlignment()) != 0) {
                size += CURRENT_JVM_INFORMATION.getObjectAlignment() - (size % CURRENT_JVM_INFORMATION.getObjectAlignment());
            }
            return Math.max(size, CURRENT_JVM_INFORMATION.getMinimumObjectSize());
        }
    }
{@inheritDoc}