My understanding is, until the method returns, the variable stays on the stack. Which means any object referenced by it is alive until the method returns.
The JIT is free to remove the object reference ("variable") any time after it's last usage, so this is not necessarily true.
as long as a reference to the object exists on the stack, it won't be garbage collected
This is true - but the JIT may change when this variable no longer "exists on the stack" in a way that doesn't necessarily match your code.
In C# 5, this can get really confusing, as well, as async methods can get rewritten in ways that variables stick around longer than you'd expect in some scenarios.
That being said, if you need to guarantee that an object is eligible at some point, setting the variable(s) referencing the object to null explicitly allows you to control when it becomes eligible explicitly.