HeapMemoryRulepublic class HeapMemoryRule extends ThreadRatioRule implements com.sun.enterprise.web.connector.grizzly.TaskListenerBased on the application context-root, configure the ReadTask
Pipeline based on the policy metric defined in domain.xml. |
Fields Summary |
---|
protected static final ConcurrentHashMap | memoryAllowedThe memory allocated per application. | private static long | availableMemoryThe memory available at startup. | protected static final ConcurrentHashMap | appMemoryUsageCache application memory usage approximation. | protected static final ConcurrentHashMap | contextRootyCacheCache the context-root assocated with a ReadTask | private static HeapMemoryRulePipeline | hmrPipelineA customized Pipeline used to measure the memory used
by an application. | private static com.sun.enterprise.web.connector.grizzly.Pipeline | defaultPipelineThe default Pipeline used by application that are
allowed to execute. | private static ConcurrentHashMap | consolidatedMemoryUsedThe consolidated amount of memory an application is using. | private Object[] | lockSimple lock. |
Methods Summary |
---|
public java.lang.Integer | call()
// ------------------------------------------------ Pipeline ------------//
synchronized(lock){
if (availableMemory == -1L){
availableMemory = usedMemory();
}
if ( hmrPipeline == null ) {
hmrPipeline = new HeapMemoryRulePipeline();
hmrPipeline.initPipeline();
hmrPipeline.startPipeline();
}
}
String token = getContextRoot();
Long memoryAllowedSize = memoryAllowed.get(token);
Double allowedRatio = privilegedTokens.get(token);
Pipeline pipeline = pipelines.get(token);
synchronized(lock){
if ( pipeline == null ){
if ( defaultPipeline == null) {
defaultPipeline = newPipeline(readTask.getPipeline()
.getMaxThreads(),readTask.getPipeline());
}
pipelines.put(token,defaultPipeline);
readTask.setPipeline(defaultPipeline);
} else {
readTask.setPipeline(pipeline);
}
}
// If no policy metry has been defined for this token and there
// is free memory, allow execution.
if ( memoryAllowedSize == null && allowedRatio == null){
if ( countReservedMemory() <= availableMemory) {
return IsolationRulesExecutor.RULE_OK_NOCACHE;
}
if ( allocationPolicy.equals(RESERVE) )
return IsolationRulesExecutor.RULE_BLOCKED;
else if ( allocationPolicy.equals(CEILING) )
return IsolationRulesExecutor.RULE_DELAY;
}
boolean isAllowed =
isAllowedToExecute(token,memoryAllowedSize,allowedRatio);
pipeline = pipelines.get(token);
if ( pipeline != null)
readTask.setPipeline(pipeline);
if ( !isAllowed ) {
if ( allocationPolicy.equals(RESERVE) )
return IsolationRulesExecutor.RULE_BLOCKED;
else if ( allocationPolicy.equals(CEILING) )
return IsolationRulesExecutor.RULE_DELAY;
}
return IsolationRulesExecutor.RULE_OK_NOCACHE;
| private long | countReservedMemory()Return the total memory required by application which has a policy
metric defined.
Iterator<Long> iterator = memoryAllowed.values().iterator();
long count = 0L;
while (iterator.hasNext()){
count += iterator.next();
}
return count;
| protected boolean | isAllowedToExecute(java.lang.String token, java.lang.Long memoryAllowedSize, java.lang.Double allowedRatio)Determine if an application can execute based on its policy metric and
method.
long currentMemory = usedMemory();
// First request, needs to calculate the ratio.
if ( memoryAllowedSize == null ){
memoryAllowedSize =
(availableMemory * allowedRatio.longValue())/100;
// We must find the allowed size based on the ratio.
memoryAllowed.put(token,memoryAllowedSize);
}
if ( memoryAllowedSize > currentMemory) {
return false;
}
// Do we know how much memory is used?
Long usage = appMemoryUsage.get(token);
contextRootyCache.put(readTask,token);
// If null, we must execute the task to find how much memory
// the app consume.
if ( usage == null) {
pipelines.put(token,hmrPipeline);
return true;
}
// Make sure we can get all memory consumed by the application
Long currentAppUsage = consolidatedMemoryUsed.get(token);
if ( currentAppUsage == null ) {
currentAppUsage = 0L;
}
usage = currentAppUsage + usage;
if ( usage > currentMemory ) return false;
if ( usage > memoryAllowedSize ) return false;
consolidatedMemoryUsed.put(token,usage);
readTask.addTaskListener(this);
return true;
| public void | taskEvent(com.sun.enterprise.web.connector.grizzly.TaskEvent event)Reduce the memory usage count when an application complete its execution.
if ( event.getStatus() == TaskEvent.COMPLETED){
String token = contextRootyCache.remove(event.attachement());
if ( token != null ) {
Long count = consolidatedMemoryUsed.get(token);
count -= appMemoryUsage.get(token);
consolidatedMemoryUsed.put(token,count);
}
}
| private static long | usedMemory()Predict the current memory
Runtime.getRuntime().gc();
return Runtime.getRuntime().totalMemory ()
- Runtime.getRuntime().freeMemory ();
|
|