Here are some just general tips. Try these and see how it improves the memory usage.
1. Don't do += here. It's totally unnecessary. In this case, it won't impact memory because we're talking about a short array of strings, but it really can because += will create a duplicate object in memory during the operation. Better choice is to just build the array in one statement, e.g. $vcenter = @( "vcenter1", "vcenter2", "vcenter3" )
2. I see no reason to do the connect and disconnects in the loop. Do them all up front. Honestly, unless you are talking about a scheduled job that has to run in its own session, I connect in my powershell profile and only seldomly disconnect, and I leave that logic out of my scripts, but I suppose that is a preference thing. Putting it in the loop however is taking up needless time. Also note that I find that the first operation following a connect is very slow. Connect-VIServer will accept multiple host names in an array, did you know that? You can actually work with more hosts simultaneously than is possible using the GUI. Just try it: connect-viserver $vcenter
3. As mentioned before, foreach will do everything inside the loop before continuing, thus everything that happens inside the {}'s will add up to more RAM usage. Often this is fine, but obviously those objects returned from Get-View are large enough and you have enough of them such that this is an issue for you and is the main cause of your memory consumption. Get-View -viewtype is very quick, but the objects it returns are also very rich and contain a lot of information. I think you will see that VMware will improve the efficiency of PowerCLI overall to give you more options here. Here's another way to do it:
$viserver = 'server1', 'server2', 'server3'
connect-viserver $viserver
get-cluster | get-vm | select Name, { $_.Guest.OSFullName } | export-csv file.csv -notypeinformation
You could improve the last line by adding the Name=, Expression= stuff.