private ReducerEstimatedJvmCost computeShuffleSortJvmCost(Reducer fReducer, Reducer eReducer, float eTempObj, float eFix, JvmModel fSSPhaseMax) {
	    //[-----------------Runtime().maxMemory()-----------------------]
	    //[-------------inMemSegBuffer 70%---------------][--for other--]
		//[------mergeBuffer 66%-------][--Write Buffer--]
		ReducerBuffer eBuffer = eReducer.getReducerBuffer();
		//float runtime_maxMemory_MB = eBuffer.getRuntime_maxMemoryMB(); 
		float inMemSegBuffer = eBuffer.getMemoryLimitMB();
		float mergeBuffer = eBuffer.getInMemoryBufferLimitMB();
		
		//float fShuffleBytesMB = (float) ((double)fReducer.getReducerCounters().getReduce_shuffle_bytes() / (1024 * 1024));
		float eShuffleBytesMB = (float) ((double)eReducer.getReducerCounters().getReduce_shuffle_raw_bytes() / (1024 * 1024));
		
		float eOGCMX = gcCap.geteOGCMX();
		float eOGC = gcCap.geteOGC();
		float eNGCMX = gcCap.geteNGCMX();
		float eEdenC = gcCap.geteEC();
		float xms = newConf.getXms();
		float enOU;  //estimated minimum usage of old generation
		float exOU;  //estimated maximum usage of old generation
		float eNewU; //estimated usage of new generation
		
		
		String ssReason;
		
		//new generation can hold all the shuffle bytes and accompanying temp objects
		if(eShuffleBytesMB + eTempObj < eEdenC) { //without YGC
			enOU = 0;
			exOU = 0;
			eNewU = eShuffleBytesMB + eTempObj;
			ssReason = "eShuffleBytesMB + eTempObj < eEdenC";
		}
		
		else if(eShuffleBytesMB + eTempObj <= eNGCMX) { //NGC can contain all the objects
			if(xms == 0) { //-Xms isn't set
				enOU = mergeBuffer;
				exOU = inMemSegBuffer;
				eNewU = eShuffleBytesMB + eTempObj;
				ssReason = "xms = 0, eEdenC < eShuffleBytesMB + eTempObj <= eNGCMX";
			}
			else { //EdenMX <= eShuffleBytesMB + eTempObj <= NGCMX
				enOU = 0;
				exOU = mergeBuffer;
				eNewU = eShuffleBytesMB + eTempObj;
				ssReason = "xms = xmx, eEdenMX <= eShuffleBytesMB + eTempObj <= eNGCMX";
			}
		}
		
		else { //eShuffleBytesMB + eTempObj > eNGCMX
			//if(eOGCMX < mergeBuffer) {
			//	System.err.println("eOGCMX is too small! eOGCMX = " + eOGCMX + ", mergeBuffer = " + mergeBuffer);
			//}
			
			if(xms == 0) {
				if(inMemSegBuffer < eOGC) {
					enOU = mergeBuffer; // maybe enOU = Math.min(eShuffleBytesMB, inMemSegBuffer);
					
				    exOU = inMemSegBuffer;
					eNewU = eNGCMX;
					ssReason = "eShuffleBytesMB + eTempObj > eNGCMX, xms = 0, inMemSegBuffer < eOGC";
				}
				else { //inMemSegBuffer >= eOGC
					enOU = Math.min(eOGC, mergeBuffer);
					if(eShuffleBytesMB / eOGCMX >= 2)
						exOU = eOGCMX;
					else
						exOU = Math.min(inMemSegBuffer, eOGCMX);
					eNewU = eNGCMX;
					ssReason = "eShuffleBytesMB + eTempObj > eNGCMX, xms = 0, inMemSegBuffer >= eOGC";
				}
			}
			
			else {
				if(inMemSegBuffer < eOGCMX) {
					enOU = inMemSegBuffer; // need more consideration
					exOU = eOGCMX;
					eNewU = eNGCMX;
					ssReason = "eShuffleBytesMB + eTempObj > eNGCMX, xms = xmx, inMemSegBuffer < eOGC";
				}
				
				else {
					enOU = mergeBuffer;
					exOU = eOGCMX;
					eNewU = eNGCMX;
					ssReason = "eShuffleBytesMB + eTempObj > eNGCMX, xms = xmx, inMemSegBuffer >= eOGC";
				}
			}
		}
		
			
		enOU = Math.min(eShuffleBytesMB, enOU + eFix);
		exOU = Math.min(eShuffleBytesMB, exOU + eFix); 
		
		// estimate the Perm Generation
		float ePermUsed = fSSPhaseMax.getPermUsed();	
		
		ReducerEstimatedJvmCost jvmCost = new ReducerEstimatedJvmCost();
		jvmCost.setSSPermUsed(ePermUsed);
		jvmCost.setSSNewUsed(eNewU);
		jvmCost.setSSnOU(enOU);
		jvmCost.setSSxOU(exOU);
		jvmCost.setSSnHeapU(enOU + eNewU);
		jvmCost.setSSxHeapU(exOU + eNewU);
		jvmCost.setSSTempObj(eTempObj);
		jvmCost.setSSFix(eFix);
		jvmCost.setSSReason(ssReason);
		
		jvmCost.seteShuffleBytesMB(eShuffleBytesMB);
		jvmCost.setMergeBuffer(mergeBuffer);
		jvmCost.setInMemSegBuffer(inMemSegBuffer);
		
		return jvmCost;
		
	}