Normally UGens are defined within the scope of a shred, this may be a sporked function or the "main shred", being the code in a file outside of any functions or classes.
When the shred a UGen was defined in exits the UGen will be disconnected from anything it connected to (I'm not sure everything that connects to the Ugen on the other end will also be disconected but that doesn't matter much here). Because of this the DAC will no longer poll it for new samples so it won't take any CPU anymore. This, in adition to calculation order, is the big advantage of the "pull through" model we use for the UGens.
CPU-wise you should be fine but the memory used for these UGens probably still won't be freed. I think that in this case you should be able to free the memory by assigning "null" to the UGen instances; I never tried that myself in practice but it was supposed to work.
That leaves object creation as a potential source of CPU spikes. You certainly *can* cause glitches by creating objects but it doesn't need to happen. I think results will depend on the complexity of a single voice, the amount of voices in use at the time, the speed of the CPU and the size of your buffer (which also affects latency). I don't think there is a substitute for simply trying it out and seeing how far you get. In this case I'd take that route, if/when you also add note-off signals instead of knowing the length at the start you will need a infrastructure for that that will likely also make voice cycling more easy.
Hope that help,
Kas.