📄 garbagecollectionservice.java
字号:
}
_gcLowWaterThreshold = low;
// read the memory check interval and fix it if it falls
// outside the constraints
int mem_interval = gc_config.getMemoryCheckInterval();
if ((mem_interval > 0) &&
(mem_interval < 5)) {
mem_interval = 5;
}
_memoryCheckInterval = mem_interval * 1000;
// read the gc interval, which is optional
int gc_interval = gc_config.getGarbageCollectionInterval();
if (gc_interval <= 0) {
gc_interval = 0;
}
_gcInterval = gc_interval * 1000;
// read the gc thread priority
int gc_priority = gc_config.getGarbageCollectionThreadPriority();
if (gc_priority < Thread.MIN_PRIORITY) {
gc_priority = Thread.MIN_PRIORITY;
}
if (gc_priority > Thread.MAX_PRIORITY) {
gc_priority = Thread.MAX_PRIORITY;
}
_gcThreadPriority = gc_priority;
}
/**
* Check whether the low water threshold has been reached.
*
* @return boolean - true if it has; false otherwise
*/
public boolean belowLowWaterThreshold() {
boolean result = false;
long threshold = (long) ((Runtime.getRuntime().totalMemory() / 100) *
_gcLowWaterThreshold);
long free = Runtime.getRuntime().freeMemory();
if (_log.isDebugEnabled()) {
_log.debug("GC Threshold=" + threshold + " Free=" + free);
}
if (threshold > free) {
result = true;
}
return result;
}
/**
* Register an entity that wishes to participate in the garbage collection
* process. This entity will be added to the list of other registered
* entities and will be called when GC is triggered.
*
* @param entry - entry to add to list
*/
public void register(GarbageCollectable entry) {
if (entry != null) {
synchronized (_gcList) {
_gcList.add(entry);
}
}
}
/**
* Unregister the specified entry from the list of garbge collectable
* entities
*
* @param entry - entry to remove
*/
public void unregister(GarbageCollectable entry) {
if (entry != null) {
synchronized (_gcList) {
_gcList.remove(entry);
}
}
}
// override ServiceManager.run
public void run() {
// do nothing
}
// override ServiceManager.start
public void start()
throws ServiceException {
// register an event with the event manager
if (_memoryCheckInterval > 0) {
_log.info("Registering Garbage Collection every " +
_memoryCheckInterval + " for memory.");
registerEvent(CHECK_FREE_MEMORY_EVENT, _memoryCheckInterval);
}
// optionally start garbage collection
if (_gcInterval > 0) {
_log.info("Registering Garbage Collection every " +
_gcInterval + " for other resources.");
registerEvent(GARBAGE_COLLECT_EVENT, _gcInterval);
}
this.setState(ServiceState.RUNNING);
}
// override ServiceManager.stop
public void stop()
throws ServiceException {
this.setState(ServiceState.STOPPED);
}
// implementation of EventHandler.getHandle
public HandleIfc getHandle() {
return null;
}
// implementation of EventHandler.handleEvent
public void handleEvent(int event, Object callback, long time) {
boolean valid_event = false;
try {
if (event == CHECK_FREE_MEMORY_EVENT) {
valid_event = true;
try {
// collect garbage only below threshold
if (belowLowWaterThreshold()) {
_log.info("GC Collecting Garbage Free Heap below "
+ _gcLowWaterThreshold);
collectGarbage(true);
}
} catch (Exception exception) {
_log.error("Error in GC Service [CHECK_FREE_MEMORY_EVENT]",
exception);
}
} else if (event == GARBAGE_COLLECT_EVENT) {
valid_event = true;
try {
// collect garbage now
collectGarbage(false);
} catch (Exception exception) {
_log.error("Error in GC Service [GARBAGE_COLLECT_EVENT]",
exception);
}
}
} finally {
if (valid_event) {
try {
registerEvent(event, ((Long) callback).longValue());
} catch (Exception exception) {
_log.error("Error in GC Service", exception);
}
}
}
}
/**
* Iterate through the list of registered {@link GarbageCollectables}
* and call collectGarbage on all of them.
*
* @param aggressive - true ofr aggressive garbage collection
*/
private void collectGarbage(boolean aggressive) {
synchronized (_gcGuard) {
if (_collectingGarbage) {
// if we are in the middle of collecting garbage then
// we can ignore this request safely.
return;
} else {
_collectingGarbage = true;
}
}
// if we get this far then we are the only thread that will
// trigger garbage collection. First we must set the priority
// of this thread
int oldPriority = Thread.currentThread().getPriority();
try {
Thread.currentThread().setPriority(_gcThreadPriority);
Object[] list = _gcList.toArray();
for (int index = 0; index < list.length; index++) {
try {
GarbageCollectable collectable =
(GarbageCollectable) list[index];
collectable.collectGarbage(aggressive);
} catch (Exception exception) {
_log.error("Error while collecting garbage", exception);
}
}
} finally {
Thread.currentThread().setPriority(oldPriority);
}
// we have finished collecting garbage
synchronized (_gcGuard) {
_collectingGarbage = false;
}
}
/**
* Register the specified event with the corresponding time with the
* {@link BasicEventManager}. It will throw an exception if it cannot
* contact the event manager or register the event.
*
* @param event - the event to register
* @param time - the associated time
* @throws GarbageCollectionServiceException
*/
private void registerEvent(int event, long time)
throws GarbageCollectionServiceException {
try {
BasicEventManager.instance().registerEventRelative(
new Event(event, this, new Long(time)), time);
} catch (IllegalEventDefinedException exception) {
// rethrow as a more relevant exception
throw new GarbageCollectionServiceException(
"Failed to registerEvent " + exception);
}
}
} //-- GarbageCollectionService
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -