Well - high memory consumption of a .NET process does not indicate a leak. The GC may just be deferring reclaiming of memory. It's actually not hard to say if there is a leak. A leak will be evident over time, exhibited as steady growth
in memory usage in the process, as new/destroy is called repeatedly. I suggest that read up on diagnosing .NET leaks if you like; but high memory usage, by itself, is not evidence of a leak.
As for optimizing the write speed of a ZipOutputStream, there is no hard and fast rule. It depends on many things, including your machine configuration, other processes contending for resources, the design of your application, the throughput available in
your I/O channel. The only way to optimize is to test in your real-world scenario.
I am not sure what you are attempting to accomplish with 'not running out of queue elements" and only scheduling the ZipOutputStream after a certain point. My impression is that you are attempting to do too much within your application regarding the
concurrency management and memory management. These are jobs best left to the .NET CLR.
You may want to look into QueueUserWorkItem - a .NET method that lets you run background tasks on the threadpool. In .NET 4.0 you can get a better facility with Tasks. Using those things means less application-level management of concurrency.
Instead you let .NET manage the concurrency for you. This is probably the best approach in most cases. In .NET 4.0 you can pipeline Tasks, so that you need not worry whether input or output is faster or slower. the Task scheduler balances things
As for this question:
> Is there any indicator to specify when I could destroy output or input streams safely?
I don't understand. Destroy the object when you are finished with the object. When it goes out of the using scope, it will be destroyed; let the GC handle memory reclamation. You generally do not need to worry about it.