Given a garbage-collected framework, when using an IOC container to inject purely stateless services, is it generally better to use the container's single-instance lifespan or to recreate the object each time it is used and throw it, and all its dependencies, away as soon as you're done with them?
You mention that your service has dependencies.
If any dependency in your graph of dependencies is not completely stateless, or if one of your dependencies in your graph of dependencies should be modified to be not so completely stateless anymore, then the whole system will fail. And the errors you get will probably be very cryptic, thus making it difficult to discover the problem.
Say you are a team of developers working on the project. It is highly unlikely that each and every one of them are aware that IOC configuration requires all these components to stay completely stateless. They may know it now, but that awareness will fade over time. And if you hire a new guy, he/she will not be aware either.
So I would definitely set up the IOC container to return a new instance every time. It is simply the safer choice, imho.
I would certainly not worry about resources. The cost of construction and garbage collection of objects is probably insignificant compared to e.g. just a single database lookup.
The single-instance was the default behavior of Spring for a reason--a single instance of a stateless service is going it consume fewer resources that the constant creation and garbage collection of many instances. Moreover, there is no real danger in sharing a stateless service, but there are some real scalability issues with creating multiple instances of a service.
So, I'd say the single-instance is most likely going to be your friend.
Without further context, I think it doesn't really matter.
You can get the benefits of short-lived objects from a single instance, if that instance simply creates the short-lived objects for every call, and you can get the benefits of a single instance from many short-lived object, if those merely act as flyweights.
Of course it's unnecessarily noisy to set it up one way, only to delegate to the opposite. So I guess you should just have a guess, whether you're likely to add state at all, and if so, whether it's going to be persistent/global state (e.g. when adding a cache) or short-lived/local state.