blob: 5fd8b2670172aab02aedfa9797b70ac43d8de8d0 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.sysds.utils;
/**
* Memory Estimates is a helper class containing static classes that estimate the memory requirements of different types
* of objects in java. All estimates are worst case JVM x86-64bit uncompressed object pointers.
*
* This in practice means that the objects are most commonly smaller, for instance the object references are often time.
*
* If the memory pressure is low (there is a low number of allocated objects) then object pointers are 4 bits.
*/
public class MemoryEstimates {
// private static final Log LOG = LogFactory.getLog(MemoryEstimates.class.getName());
/**
* Get the worst case memory usage of an java.util.BitSet java object.
*
* @param length The length of the array.
* @return The memory estimate in bytes
*/
public static double bitSetCost(long length) {
double size = 0;
size += 8; // object reference
size += longArrayCost(length / 64 + (length % 64 > 0 ? 1 : 0));
size += 4; // words in Use
size += 1; // size is Sticky
size += 3; // padding.
return size;
}
/**
* Get the worst case memory usage of an array of booleans.
*
* Unfortunately in java booleans are allocated as bytes.
*
* @param length The length of the array.
* @return The memory estimate in bytes.
*/
public static double booleanArrayCost(long length) {
return byteArrayCost(length);
}
/**
* Get the worst case memory usage of an array of bytes.
*
* @param length The length of the array.
* @return The memory estimate in bytes
*/
public static double byteArrayCost(long length) {
long size = 0;
size += 8; // Byte array Reference
size += 20; // Byte array Object header
if(length <= 4) { // byte array fills out the first 4 bytes differently than the later bytes.
size += 4;
}
else { // byte array pads to next 8 bytes after the first 4.
size += length;
double diff = (length - 4) % 8;
if(diff > 0) {
size += 8 - diff;
}
}
return size;
}
/**
* Get the worst case memory usage of an array of chars.
*
* @param length The length of the array.
* @return The memory estimate in bytes
*/
public static double charArrayCost(long length) {
double size = 0;
size += 8; // char array Reference
size += 20; // char array Object header
if(length <= 2) { // char array fills out the first 2 chars differently than the later bytes.
size += 4;
}
else {
size += length * 2;// 2 bytes per char
double diff = (length * 2 - 4) % 8;
if(diff > 0) {
size += 8 - diff; // next object alignment
}
}
return size;
}
/**
* Get the worst case memory usage of an array of integers.
*
* @param length The length of the array.
* @return The memory estimate in bytes
*/
public static double intArrayCost(long length) {
double size = 0;
size += 8; // _ptr int[] reference
size += 20; // int array Object header
if(length <= 1) {
size += 4;
}
else {
size += 4d * length; // offsets 4 bytes per int
if(length % 2 == 0)
size += 4;
}
return size;
}
/**
* Get the worst case memory usage of an array of integers.
*
* @param length The length of the array.
* @return The memory estimate in bytes.
*/
public static double floatArrayCost(long length) {
// exact same size as intArrayCost
return intArrayCost(length);
}
/**
* Get the worst case memory usage of an array of doubles.
*
* @param length The length of the array.
* @return The memory estimate in bytes
*/
public static final double doubleArrayCost(long length) {
double size = 0;
size += 8; // _values double array reference
size += 20; // double array object header
size += 4; // padding inside double array object to align to 8 bytes.
size += 8d * length; // Each double fills 8 Bytes
return size;
}
/**
* Get the worst case memory usage for an array of objects.
*
* Note this does not take into account each objects allocated variables, just the objects themselves.
*
* @param length The length of the array.
* @return The memory estimate in bytes
*/
public static final double objectArrayCost(long length) {
double size = 0;
size += 8d; // reference to array
size += 20d; // header
size += 4d; // padding before first reference
size += 8d * length; // references to all objects.
return size;
}
/**
* Get the worst case memory usage for an array of longs
*
* @param length The length of the array.
* @return The memory estimate in bytes
*/
public static final double longArrayCost(long length) {
// exactly the same size as a double array
return doubleArrayCost(length);
}
/**
* Get the worst case memory usage of an array containing strings.
*
* In case anyone is wondering ... strings are expensive.
*
* @param strings The strings array.
* @return The array memory cost
*/
public static final double stringArrayCost(String[] strings) {
double size = 0;
int i = 0;
int by8 = strings.length - strings.length %8 ;
for(;i < by8; i+= 8)
size += stringArrayCostVec8(strings, i);
for(; i < strings.length; i++)
size += stringCost(strings[i]);
return size;
}
private static final double stringArrayCostVec8(String[] strings, int r){
long size = 0;
size += stringCost(strings[r]);
size += stringCost(strings[r+1]);
size += stringCost(strings[r+2]);
size += stringCost(strings[r+3]);
size += stringCost(strings[r+4]);
size += stringCost(strings[r+5]);
size += stringCost(strings[r+6]);
size += stringCost(strings[r+7]);
return size;
}
public static final double stringArrayCost(int length, int avgStringLength){
// if null 16 object + 8 array ref
return stringCost(avgStringLength) * length + 24.0d;
}
/**
* Get the worst case memory usage of a single string.
*
* In case anyone is wondering ... strings are expensive.
*
* @param value The String to measure
* @return The size in memory.
*/
public static long stringCost(String value) {
// if null 16 object + 8 array ref
return value == null ? 24L : stringCost(value.length()); // char array
}
/**
* Get the worst case memory usage of a single string, assuming given length.
*
* @param length The length of the string
* @return The size in memory
*/
public static long stringCost(long length) {
// 16 object
// 4 hash
// 8 array ref
// 32 char array
// total base : 60
return 60L + length * 2L; // char array
}
}