Why knowing whether some piece of memory is needed is undecidable?
So you can modify any program to allocate some space on the heap and only access it if the original program terminates. An optimal garbage collector would then only collect the memory if the program does not terminate.
Can we decide if a program will terminate or not?
All garbage collectors I'm familiar with work by collecting memory which can no longer be accessed, e.g. all (the transitive closure of) variables pointing to it went out of scope. But that's an under-approximation of the set of of memory spaces that can be collected, because at any point a memory location may still have a variable pointing to it in scope, yet it will never be accessed again.
Finding the precise set of memory spaces that can be collected is trivially reducible to any undecided problem - for example, find the set of memory spaces that can be collected at point A in the following program:
x = allocate()
// Point A
if (result of some known-to-be-undecidable problem is true):
print(x)
And so finding that set is undecidable in itself.