Для высвобождения памяти закрывай буферы командой
bwipeout, или
bunload, если нужно оставить название буфера в списке. Скрытые буферы можно массово чистить самописной командой:
UPD: Оказалось, что для корректной работы некоторых плагинов нужно оставлять хотя бы один последний скрытый буфер, поэтому немного обновил код, добавив возможность настроить их количество, а так же явный режим force (!) для команды. Возможно уже стоит всё это вынести в плагин, где можно будет нормально переписать код и оптимально разделить функционал, к примеру, добавить кэширование и возможность сохранять буферы.
let g:bufcleaner_max_save = 2
command! -bar -bang -nargs=? CleanBuffers call s:cleanBuffers("<bang>")
function! s:cleanBuffers(...) abort
let force = a:0 >= 1 && a:1 ==# '!'
redir => bufs
silent! buffers
redir END
let hidden = []
for buf in map(split(bufs, '\n'), 'split(v:val)')
let bufnr = buf[0] + 0
let flags = matchstr(join(buf[1:]), '^.*\ze\s\+"')
let mod = substitute(flags, '\s*', '', 'g')
let hide = mod ==# 'h' || mod ==# 'h+'
\ && (force || input(printf("\n%s not saved.\nDelete anyway? [Y]es, (N)o: ",
\ bufname(bufnr))) =~? '^y\%[es]$')
if hide
call add(hidden, bufnr)
endif
endfor
let saved = get(g:, 'bufcleaner_max_save', 3)
let target = len(hidden) > saved ? join(hidden[0:-saved-1], ' ') : ''
if !empty(target)
silent! execute 'bwipeout!' target
endif
endfunction
Очищать при скрытие:
augroup buffer-cleaner
autocmd!
autocmd BufHidden * CleanBuffers
augroup END