
org.neo4j.kernel.AutoConfigurator Maven / Gradle / Ivy
/**
* Copyright (c) 2002-2013 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
package org.neo4j.kernel;
import java.io.File;
import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import org.neo4j.kernel.impl.nioneo.store.FileSystemAbstraction;
public class AutoConfigurator
{
private final int totalPhysicalMemMb;
private final int maxVmUsageMb;
private final File dbPath;
private final boolean useMemoryMapped;
private final FileSystemAbstraction fs;
public AutoConfigurator( FileSystemAbstraction fs, File dbPath, boolean useMemoryMapped )
{
this( fs, dbPath, useMemoryMapped, physicalMemory(), Runtime.getRuntime().maxMemory() );
}
AutoConfigurator( FileSystemAbstraction fs, File dbPath, boolean useMemoryMapped, long physicalMemory, long vmMemory )
{
this.fs = fs;
this.dbPath = dbPath;
this.useMemoryMapped = useMemoryMapped;
if ( physicalMemory != -1 )
{
totalPhysicalMemMb = (int) (physicalMemory / 1024 / 1024);
}
else
{
totalPhysicalMemMb = -1;
}
maxVmUsageMb = (int) (vmMemory / 1024 / 1024);
}
private static long physicalMemory()
{
OperatingSystemMXBean osBean =
ManagementFactory.getOperatingSystemMXBean();
long mem = -1;
try
{
Class> beanClass =
Thread.currentThread().getContextClassLoader()
.loadClass( "com.sun.management.OperatingSystemMXBean" );
Method method = beanClass.getMethod( "getTotalPhysicalMemorySize" );
mem = (Long) method.invoke( osBean );
}
catch ( Exception e )
{ // ok we tried but probably 1.5 JVM or other class library implementation
}
catch ( LinkageError e )
{ // ok we tried but probably 1.5 JVM or other class library implementation
}
return mem;
}
public String getNiceMemoryInformation()
{
return "Physical mem: " + totalPhysicalMemMb + "MB, Heap size: " + maxVmUsageMb + "MB";
}
public Map configure()
{
Map autoConfiguredConfig = new HashMap();
if ( totalPhysicalMemMb > 0 )
{
if ( useMemoryMapped )
{
int availableMem = (totalPhysicalMemMb - maxVmUsageMb);
// leave 15% for OS and other progs
availableMem -= (int) (availableMem * 0.15f);
assignMemory( autoConfiguredConfig, availableMem );
}
else
{
// use half of heap (if needed) for buffers
assignMemory( autoConfiguredConfig, maxVmUsageMb / 2 );
}
}
return autoConfiguredConfig;
}
private int calculate( int memLeft, int storeSize, float use, float expand, boolean canExpand )
{
int size;
if ( storeSize > (memLeft * use) )
{
size = (int) (memLeft * use);
}
else if ( canExpand )
{
if ( (storeSize * expand * 5 < memLeft * use) )
{
size = (int) (memLeft * use / 5);
}
else
{
size = (int) (memLeft * use);
}
}
else
{
size = storeSize;
}
return size;
}
private void assignMemory( Map config, int availableMem )
{
int nodeStore = getFileSizeMb( "nodestore.db" );
int relStore = getFileSizeMb( "relationshipstore.db" );
int propStore = getFileSizeMb( "propertystore.db" );
int stringStore = getFileSizeMb( "propertystore.db.strings" );
int arrayStore = getFileSizeMb( "propertystore.db.arrays" );
int totalSize = nodeStore + relStore + propStore + stringStore + arrayStore;
boolean expand = false;
if ( totalSize * 1.15f < availableMem )
{
expand = true;
}
int memLeft = availableMem;
relStore = calculate( memLeft, relStore, 0.75f, 1.1f, expand );
memLeft -= relStore;
nodeStore = calculate( memLeft, nodeStore, 0.2f, 1.1f, expand );
memLeft -= nodeStore;
propStore = calculate( memLeft, propStore, 0.75f, 1.1f, expand );
memLeft -= propStore;
stringStore = calculate( memLeft, stringStore, 0.75f, 1.1f, expand );
memLeft -= stringStore;
arrayStore = calculate( memLeft, arrayStore, 1.0f, 1.1f, expand );
memLeft -= arrayStore;
configPut( config, "nodestore.db", nodeStore );
configPut( config, "relationshipstore.db", relStore );
configPut( config, "propertystore.db", propStore );
configPut( config, "propertystore.db.strings", stringStore );
configPut( config, "propertystore.db.arrays", arrayStore );
}
private void configPut( Map config, String store, int size )
{
// Don't overwrite explicit config
String key = "neostore." + store + ".mapped_memory";
config.put( key, size + "M" );
}
private int getFileSizeMb( String file )
{
long length = fs.getFileSize( new File( dbPath, "neostore." + file ) );
int mb = (int) (length / 1024 / 1024);
if ( mb > 0 )
{
return mb;
}
// default return 1MB if small or empty file
return 1;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy