the idea here is, user has an expectation on the maximum cores to assign to the application, but this expectation is usually not achievable due to the limited cores in each worker; 

so the allocation here is to decide executorNum per Worker according to the memory space on each worker (because this is a hard limitation), and meet the user's expectation on the cores with the best efforts