Perhaps write to disk, delete, read from disk? The only potential problem I can foresee with this approach is that any relationships between parent/child environments will be lost. But if you're simply trying to copy the values from one environment to another, maybe this isn't a problem?
Update:
I cannot replicate what you say about the copy approach. The code below shows that the maximum memory used (as reported by gc) does not increase. This is because the values are "promised", not deep-copied. A copy will be made, however, if you change an object in the new environment before you delete it from the old environment.
R> e1 <- new.env()
R> e1$x <- numeric(5e7)
R> e1$y <- numeric(5e7)
R> gc()
used (Mb) gc trigger (Mb) max used (Mb)
Ncells 171022 9.2 350000 18.7 350000 18.7
Vcells 100271746 765.1 110886821 846.0 100272535 765.1
R> e2 <- new.env()
R> for(n in ls(e1, all.names=TRUE))
+ assign(n, get(n, e1), e2)
R> gc()
used (Mb) gc trigger (Mb) max used (Mb)
Ncells 171038 9.2 350000 18.7 350000 18.7
Vcells 100271788 765.1 116511162 889.0 100272535 765.1
R> identical(e1$x,e2$x)
[1] TRUE
R> identical(e1$y,e2$y)
[1] TRUE