// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.tools; import static org.openstreetmap.josm.tools.I18n.tr; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; import java.util.function.Supplier; import org.openstreetmap.josm.Main; /** * This class allows all components of JOSM to register reclaimable amounts to memory. *
* It can be used to hold imagery caches or other data that can be reconstructed form disk/web if required. *
* Reclaimable storage implementations may be added in the future.
*
* @author Michael Zangl
* @since 10588
*/
public class MemoryManager {
/**
* assumed minimum JOSM memory footprint
*/
private static final long JOSM_CORE_FOOTPRINT = 50L * 1024L * 1024L;
private static final MemoryManager INSTANCE = new MemoryManager();
private final ArrayList
* If there is enough free memory, the factory is used to procude one element which is then returned as memory handle.
*
* You should invoke {@link MemoryHandle#free()} if you do not need that handle any more.
* @param
* This method should be the prefered access to the memory since it will do error checking when {@link #free()} was called.
* @return The memory area content.
*/
T get();
/**
* Get the size that was requested for this memory area.
* @return the size
*/
long getSize();
/**
* Manually release this memory area. There should be no memory consumed by this afterwards.
*/
void free();
}
private class ManualFreeMemoryHandletrue
if that memory is available.
*/
public synchronized boolean isAvailable(long maxBytes) {
if (maxBytes < 0) {
throw new IllegalArgumentException(MessageFormat.format("Cannot allocate negative number of bytes: {0}", maxBytes));
}
return getAvailableMemory() >= maxBytes;
}
/**
* Gets the maximum amount of memory available for use in this manager.
* @return The maximum amount of memory.
*/
public synchronized long getMaxMemory() {
return Runtime.getRuntime().maxMemory() - JOSM_CORE_FOOTPRINT;
}
/**
* Gets the memory that is considered free.
* @return The memory that can be used for new allocations.
*/
public synchronized long getAvailableMemory() {
return getMaxMemory() - activeHandles.stream().mapToLong(MemoryHandle::getSize).sum();
}
/**
* Get the global memory manager instance.
* @return The memory manager.
*/
public static MemoryManager getInstance() {
return INSTANCE;
}
/**
* Reset the state of this manager to the default state.
* @return true if there were entries that have been reset.
*/
protected synchronized List