FileDocCategorySizeDatePackage
HeapMemoryRule.javaAPI DocGlassfish v2 API12011Fri May 04 22:37:02 BST 2007com.sun.enterprise.web.ara.rules

HeapMemoryRule

public class HeapMemoryRule extends ThreadRatioRule implements com.sun.enterprise.web.connector.grizzly.TaskListener
Based on the application context-root, configure the ReadTask Pipeline based on the policy metric defined in domain.xml.
author
Jeanfrancois Arcand

Fields Summary
protected static final ConcurrentHashMap
memoryAllowed
The memory allocated per application.
private static long
availableMemory
The memory available at startup.
protected static final ConcurrentHashMap
appMemoryUsage
Cache application memory usage approximation.
protected static final ConcurrentHashMap
contextRootyCache
Cache the context-root assocated with a ReadTask
private static HeapMemoryRulePipeline
hmrPipeline
A customized Pipeline used to measure the memory used by an application.
private static com.sun.enterprise.web.connector.grizzly.Pipeline
defaultPipeline
The default Pipeline used by application that are allowed to execute.
private static ConcurrentHashMap
consolidatedMemoryUsed
The consolidated amount of memory an application is using.
private Object[]
lock
Simple lock.
Constructors Summary
Methods Summary
public java.lang.Integercall()

    // ------------------------------------------------ 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 longcountReservedMemory()
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 booleanisAllowedToExecute(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 voidtaskEvent(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 longusedMemory()
Predict the current memory

        Runtime.getRuntime().gc();
        return Runtime.getRuntime().totalMemory () 
            - Runtime.getRuntime().freeMemory ();