public HeuristicResult apply(TezApplicationData data) {
    if(!data.getSucceeded()) {
      return null;
    }

    TezTaskData[] tasks = getTasks(data);

    List<Long> totalPhysicalMemory = new LinkedList<Long>();
    List<Long> totalVirtualMemory = new LinkedList<Long>();
    List<Long> runTime = new LinkedList<Long>();

    for (TezTaskData task : tasks) {
      if (task.isSampled()) {
        totalPhysicalMemory.add(task.getCounters().get(TezCounterData.CounterName.PHYSICAL_MEMORY_BYTES));
        totalVirtualMemory.add(task.getCounters().get(TezCounterData.CounterName.VIRTUAL_MEMORY_BYTES));
        runTime.add(task.getTotalRunTimeMs());
      }
    }

    long averagePMem = Statistics.average(totalPhysicalMemory);
    long averageVMem = Statistics.average(totalVirtualMemory);
    long maxPMem;
    long minPMem;
    try{
      maxPMem = Collections.max(totalPhysicalMemory);
      minPMem = Collections.min(totalPhysicalMemory);

    }
    catch(Exception exception){
      maxPMem = 0;
      minPMem = 0;
    }
    long averageRunTime = Statistics.average(runTime);

    String containerSizeStr;


    if(!Strings.isNullOrEmpty(data.getConf().getProperty(TEZ_MAPPER_MEMORY_CONF))
        && Long.parseLong(data.getConf().getProperty(TEZ_MAPPER_MEMORY_CONF)) > 0) {
      containerSizeStr = data.getConf().getProperty(TEZ_MAPPER_MEMORY_CONF);
    } else if(!Strings.isNullOrEmpty(data.getConf().getProperty(HIVE_MAPPER_MEMORY_CONF))
        && Long.parseLong(data.getConf().getProperty(HIVE_MAPPER_MEMORY_CONF)) > 0) {
      containerSizeStr = data.getConf().getProperty(HIVE_MAPPER_MEMORY_CONF);
    }
    else if(!Strings.isNullOrEmpty(data.getConf().getProperty(_mapredContainerMemConf))
        && Long.parseLong(data.getConf().getProperty(_mapredContainerMemConf)) > 0) {
      containerSizeStr = data.getConf().getProperty(_mapredContainerMemConf);
    }
    else {
      containerSizeStr = getContainerMemDefaultMBytes();
    }

    long containerSize = Long.parseLong(containerSizeStr) * FileUtils.ONE_MB;

    double averageMemMb = (double)((averagePMem) /FileUtils.ONE_MB) ;

    double ratio = averageMemMb / ((double)(containerSize / FileUtils.ONE_MB));

    Severity severity ;

    if(tasks.length == 0){
      severity = Severity.NONE;
    }
    else{
      severity = getMemoryRatioSeverity(ratio);
    }

    HeuristicResult result = new HeuristicResult(_heuristicConfData.getClassName(),
            _heuristicConfData.getHeuristicName(), severity, Utils.getHeuristicScore(severity, tasks.length));

    result.addResultDetail("Number of tasks", Integer.toString(tasks.length));
    result.addResultDetail("Maximum Physical Memory (MB)",
            tasks.length == 0 ? "0" : Long.toString(maxPMem/FileUtils.ONE_MB));
    result.addResultDetail("Minimum Physical memory (MB)",
            tasks.length == 0 ? "0" : Long.toString(minPMem/FileUtils.ONE_MB));
    result.addResultDetail("Average Physical Memory (MB)",
            tasks.length == 0 ? "0" : Long.toString(averagePMem/FileUtils.ONE_MB));
    result.addResultDetail("Average Virtual Memory (MB)",
            tasks.length == 0 ? "0" : Long.toString(averageVMem/FileUtils.ONE_MB));
    result.addResultDetail("Average Task RunTime",
            tasks.length == 0 ? "0" : Statistics.readableTimespan(averageRunTime));
    result.addResultDetail("Requested Container Memory (MB)",
            (tasks.length == 0 || containerSize == 0 || containerSize == -1) ? "0" : String.valueOf(containerSize / FileUtils.ONE_MB));


    return result;

  }
Analyzes mapper memory allocation and requirements
app/com/linkedin/drelephant/tez/heuristics/GenericMemoryHeuristic.java