package com.sleepycat.je.dbi; public class MemoryBudget { private final static int LONG_OVERHEAD_32=16; private final static int LONG_OVERHEAD_64=24; private final static int BYTE_ARRAY_OVERHEAD_32=16; private final static int BYTE_ARRAY_OVERHEAD_64=24; private final static int OBJECT_OVERHEAD_32=8; private final static int OBJECT_OVERHEAD_64=16; private final static int ARRAY_ITEM_OVERHEAD_32=4; private final static int ARRAY_ITEM_OVERHEAD_64=8; private final static int HASHMAP_OVERHEAD_32=120; private final static int HASHMAP_OVERHEAD_64=216; private final static int HASHMAP_ENTRY_OVERHEAD_32=24; private final static int HASHMAP_ENTRY_OVERHEAD_64=48; private final static int HASHSET_OVERHEAD_32=136; private final static int HASHSET_OVERHEAD_64=240; private final static int HASHSET_ENTRY_OVERHEAD_32=24; private final static int HASHSET_ENTRY_OVERHEAD_64=48; private final static int TWOHASHMAPS_OVERHEAD_32=240; private final static int TWOHASHMAPS_OVERHEAD_64=432; private final static int TREEMAP_OVERHEAD_32=40; private final static int TREEMAP_OVERHEAD_64=64; private final static int TREEMAP_ENTRY_OVERHEAD_32=32; private final static int TREEMAP_ENTRY_OVERHEAD_64=53; private final static int LN_OVERHEAD_32=24; private final static int LN_OVERHEAD_64=32; private final static int DUPCOUNTLN_OVERHEAD_32=24; private final static int DUPCOUNTLN_OVERHEAD_64=40; private final static int BIN_FIXED_OVERHEAD_32_14=344; private final static int BIN_FIXED_OVERHEAD_32_15=360; private final static int BIN_FIXED_OVERHEAD_64_15=528; private final static int DIN_FIXED_OVERHEAD_32_14=352; private final static int DIN_FIXED_OVERHEAD_32_15=360; private final static int DIN_FIXED_OVERHEAD_64_15=536; private final static int DBIN_FIXED_OVERHEAD_32_14=352; private final static int DBIN_FIXED_OVERHEAD_32_15=368; private final static int DBIN_FIXED_OVERHEAD_64_15=544; private final static int IN_FIXED_OVERHEAD_32_14=312; private final static int IN_FIXED_OVERHEAD_32_15=320; private final static int IN_FIXED_OVERHEAD_64_15=472; private final static int KEY_OVERHEAD_32=16; private final static int KEY_OVERHEAD_64=24; private final static int LOCK_OVERHEAD_32=32; private final static int LOCK_OVERHEAD_64=56; private final static int LOCKINFO_OVERHEAD_32=16; private final static int LOCKINFO_OVERHEAD_64=32; private final static int TXN_OVERHEAD_32_14=167; private final static int TXN_OVERHEAD_32_15=175; private final static int TXN_OVERHEAD_64_15=293; private final static int CHECKPOINT_REFERENCE_SIZE_32_14=32 + HASHSET_ENTRY_OVERHEAD_32; private final static int CHECKPOINT_REFERENCE_SIZE_32_15=40 + HASHSET_ENTRY_OVERHEAD_32; private final static int CHECKPOINT_REFERENCE_SIZE_64_15=56 + HASHSET_ENTRY_OVERHEAD_64; private final static int UTILIZATION_PROFILE_ENTRY_32=88; private final static int UTILIZATION_PROFILE_ENTRY_64=136; private final static int TFS_LIST_INITIAL_OVERHEAD_32=464; private final static int TFS_LIST_INITIAL_OVERHEAD_64=504; private final static int TFS_LIST_SEGMENT_OVERHEAD_32=440; private final static int TFS_LIST_SEGMENT_OVERHEAD_64=464; private final static int LN_INFO_OVERHEAD_32=24; private final static int LN_INFO_OVERHEAD_64=48; private final static int LONG_LIST_PER_ITEM_OVERHEAD_32=20; private final static int LONG_LIST_PER_ITEM_OVERHEAD_64=32; public static int LONG_OVERHEAD; public static int BYTE_ARRAY_OVERHEAD; public static int OBJECT_OVERHEAD; public static int ARRAY_ITEM_OVERHEAD; public static int HASHMAP_OVERHEAD; public static int HASHMAP_ENTRY_OVERHEAD; public static int HASHSET_OVERHEAD; public static int HASHSET_ENTRY_OVERHEAD; public static int TWOHASHMAPS_OVERHEAD; public static int TREEMAP_OVERHEAD; public static int TREEMAP_ENTRY_OVERHEAD; public static int LN_OVERHEAD; public static int DUPCOUNTLN_OVERHEAD; public static int BIN_FIXED_OVERHEAD; public static int DIN_FIXED_OVERHEAD; public static int DBIN_FIXED_OVERHEAD; public static int IN_FIXED_OVERHEAD; public static int KEY_OVERHEAD; public static int LOCK_OVERHEAD; public static int LOCKINFO_OVERHEAD; public static int TXN_OVERHEAD; public static int CHECKPOINT_REFERENCE_SIZE; public static int UTILIZATION_PROFILE_ENTRY; public static int TFS_LIST_INITIAL_OVERHEAD; public static int TFS_LIST_SEGMENT_OVERHEAD; public static int LN_INFO_OVERHEAD; public static int LONG_LIST_PER_ITEM_OVERHEAD; private final static String JVM_ARCH_PROPERTY="sun.arch.data.model"; private final static String FORCE_JVM_ARCH="je.forceJVMArch"; private long treeMemoryUsage; private long miscMemoryUsage; private Object memoryUsageSynchronizer=new Object(); private int nLockTables; private long[] lockMemoryUsage; private long trackerBudget; private long cacheBudget; private long inOverhead; private long binOverhead; private long dinOverhead; private long dbinOverhead; /** * Initialize the starting environment memory state */ void initCacheMemoryUsage() throws DatabaseException { synchronized (memoryUsageSynchronizer) { treeMemoryUsage=calcTreeCacheUsage(); } } /** * Public for testing. */ public long calcTreeCacheUsage() throws DatabaseException { long totalSize=0; INList inList=envImpl.getInMemoryINs(); totalSize=this.hook347(totalSize,inList); return totalSize; } /** * Update the environment wide tree memory count, wake up the evictor if * necessary. * @param incrementnote that increment may be negative. */ public void updateTreeMemoryUsage( long increment){ synchronized (memoryUsageSynchronizer) { treeMemoryUsage+=increment; } } /** * Update the environment wide misc memory count, wake up the evictor if * necessary. * @param incrementnote that increment may be negative. */ public void updateMiscMemoryUsage( long increment){ synchronized (memoryUsageSynchronizer) { miscMemoryUsage+=increment; } } public void updateLockMemoryUsage( long increment, int lockTableIndex){ lockMemoryUsage[lockTableIndex]+=increment; } public long accumulateNewUsage( IN in, long newSize){ return in.getInMemorySize() + newSize; } public void refreshTreeMemoryUsage( long newSize){ synchronized (memoryUsageSynchronizer) { treeMemoryUsage=newSize; } } public long getCacheMemoryUsage(){ long accLockMemoryUsage=0; if (nLockTables == 1) { accLockMemoryUsage=lockMemoryUsage[0]; } else { for (int i=0; i < nLockTables; i++) { accLockMemoryUsage+=lockMemoryUsage[i]; } } return treeMemoryUsage + miscMemoryUsage + accLockMemoryUsage; } /** * Used for unit testing. */ public long getTreeMemoryUsage(){ return treeMemoryUsage; } public long getTrackerBudget(){ return trackerBudget; } public long getCacheBudget(){ return cacheBudget; } public long getINOverhead(){ return inOverhead; } public long getBINOverhead(){ return binOverhead; } public long getDINOverhead(){ return dinOverhead; } public long getDBINOverhead(){ return dbinOverhead; } /** * Returns the memory size occupied by a byte array of a given length. */ public static int byteArraySize( int arrayLen){ int size=BYTE_ARRAY_OVERHEAD; if (arrayLen > 4) { size+=((arrayLen - 4 + 7) / 8) * 8; } return size; } protected long hook347( long totalSize, INList inList) throws DatabaseException { Iterator iter=inList.iterator(); while (iter.hasNext()) { IN in=(IN)iter.next(); long size=in.getInMemorySize(); totalSize+=size; } return totalSize; } protected void hook351( DbConfigManager configManager) throws DatabaseException { inOverhead=IN.computeOverhead(configManager); binOverhead=BIN.computeOverhead(configManager); dinOverhead=DIN.computeOverhead(configManager); dbinOverhead=DBIN.computeOverhead(configManager); original(configManager); } @MethodObject static class MemoryBudget_sinit { void execute(){ is64=false; isJVM14=true; original(); overrideArch=System.getProperty(FORCE_JVM_ARCH); try { if (overrideArch == null) { arch=System.getProperty(JVM_ARCH_PROPERTY); if (arch != null) { is64=Integer.parseInt(arch) == 64; } } else { is64=Integer.parseInt(overrideArch) == 64; } } catch ( NumberFormatException NFE) { NFE.printStackTrace(System.err); } if (is64) { if (isJVM14) { RE=new RuntimeException("1.4 based 64 bit JVM not supported"); RE.printStackTrace(System.err); throw RE; } LONG_OVERHEAD=LONG_OVERHEAD_64; BYTE_ARRAY_OVERHEAD=BYTE_ARRAY_OVERHEAD_64; OBJECT_OVERHEAD=OBJECT_OVERHEAD_64; ARRAY_ITEM_OVERHEAD=ARRAY_ITEM_OVERHEAD_64; HASHMAP_OVERHEAD=HASHMAP_OVERHEAD_64; HASHMAP_ENTRY_OVERHEAD=HASHMAP_ENTRY_OVERHEAD_64; HASHSET_OVERHEAD=HASHSET_OVERHEAD_64; HASHSET_ENTRY_OVERHEAD=HASHSET_ENTRY_OVERHEAD_64; TWOHASHMAPS_OVERHEAD=TWOHASHMAPS_OVERHEAD_64; TREEMAP_OVERHEAD=TREEMAP_OVERHEAD_64; TREEMAP_ENTRY_OVERHEAD=TREEMAP_ENTRY_OVERHEAD_64; LN_OVERHEAD=LN_OVERHEAD_64; DUPCOUNTLN_OVERHEAD=DUPCOUNTLN_OVERHEAD_64; BIN_FIXED_OVERHEAD=BIN_FIXED_OVERHEAD_64_15; DIN_FIXED_OVERHEAD=DIN_FIXED_OVERHEAD_64_15; DBIN_FIXED_OVERHEAD=DBIN_FIXED_OVERHEAD_64_15; IN_FIXED_OVERHEAD=IN_FIXED_OVERHEAD_64_15; TXN_OVERHEAD=TXN_OVERHEAD_64_15; CHECKPOINT_REFERENCE_SIZE=CHECKPOINT_REFERENCE_SIZE_64_15; KEY_OVERHEAD=KEY_OVERHEAD_64; LOCK_OVERHEAD=LOCK_OVERHEAD_64; LOCKINFO_OVERHEAD=LOCKINFO_OVERHEAD_64; UTILIZATION_PROFILE_ENTRY=UTILIZATION_PROFILE_ENTRY_64; TFS_LIST_INITIAL_OVERHEAD=TFS_LIST_INITIAL_OVERHEAD_64; TFS_LIST_SEGMENT_OVERHEAD=TFS_LIST_SEGMENT_OVERHEAD_64; LN_INFO_OVERHEAD=LN_INFO_OVERHEAD_64; LONG_LIST_PER_ITEM_OVERHEAD=LONG_LIST_PER_ITEM_OVERHEAD_64; } else { LONG_OVERHEAD=LONG_OVERHEAD_32; BYTE_ARRAY_OVERHEAD=BYTE_ARRAY_OVERHEAD_32; OBJECT_OVERHEAD=OBJECT_OVERHEAD_32; ARRAY_ITEM_OVERHEAD=ARRAY_ITEM_OVERHEAD_32; HASHMAP_OVERHEAD=HASHMAP_OVERHEAD_32; HASHMAP_ENTRY_OVERHEAD=HASHMAP_ENTRY_OVERHEAD_32; HASHSET_OVERHEAD=HASHSET_OVERHEAD_32; HASHSET_ENTRY_OVERHEAD=HASHSET_ENTRY_OVERHEAD_32; TWOHASHMAPS_OVERHEAD=TWOHASHMAPS_OVERHEAD_32; TREEMAP_OVERHEAD=TREEMAP_OVERHEAD_32; TREEMAP_ENTRY_OVERHEAD=TREEMAP_ENTRY_OVERHEAD_32; LN_OVERHEAD=LN_OVERHEAD_32; DUPCOUNTLN_OVERHEAD=DUPCOUNTLN_OVERHEAD_32; if (isJVM14) { BIN_FIXED_OVERHEAD=BIN_FIXED_OVERHEAD_32_14; DIN_FIXED_OVERHEAD=DIN_FIXED_OVERHEAD_32_14; DBIN_FIXED_OVERHEAD=DBIN_FIXED_OVERHEAD_32_14; IN_FIXED_OVERHEAD=IN_FIXED_OVERHEAD_32_14; TXN_OVERHEAD=TXN_OVERHEAD_32_14; CHECKPOINT_REFERENCE_SIZE=CHECKPOINT_REFERENCE_SIZE_32_14; } else { BIN_FIXED_OVERHEAD=BIN_FIXED_OVERHEAD_32_15; DIN_FIXED_OVERHEAD=DIN_FIXED_OVERHEAD_32_15; DBIN_FIXED_OVERHEAD=DBIN_FIXED_OVERHEAD_32_15; IN_FIXED_OVERHEAD=IN_FIXED_OVERHEAD_32_15; TXN_OVERHEAD=TXN_OVERHEAD_32_15; CHECKPOINT_REFERENCE_SIZE=CHECKPOINT_REFERENCE_SIZE_32_15; } KEY_OVERHEAD=KEY_OVERHEAD_32; LOCK_OVERHEAD=LOCK_OVERHEAD_32; LOCKINFO_OVERHEAD=LOCKINFO_OVERHEAD_32; UTILIZATION_PROFILE_ENTRY=UTILIZATION_PROFILE_ENTRY_32; TFS_LIST_INITIAL_OVERHEAD=TFS_LIST_INITIAL_OVERHEAD_32; TFS_LIST_SEGMENT_OVERHEAD=TFS_LIST_SEGMENT_OVERHEAD_32; LN_INFO_OVERHEAD=LN_INFO_OVERHEAD_32; LONG_LIST_PER_ITEM_OVERHEAD=LONG_LIST_PER_ITEM_OVERHEAD_32; } } } @MethodObject static class MemoryBudget_reset { void execute() throws DatabaseException { original(); _this.trackerBudget=true ? newTrackerBudget : newMaxMemory; _this.cacheBudget=newMaxMemory - newLogBufferBudget; _this.nLockTables=configManager.getInt(EnvironmentParams.N_LOCK_TABLES); _this.lockMemoryUsage=new long[_this.nLockTables]; } } }