If a Buffer object is backed by direct buffer, de-allocate it on close.

This uses the explicit cleaner mechanism attached to direct buffers, and adds
a set of assertions ensuring buffers are not re-used after this call.

There is no unit test for the cleaner call itself, as I can't think of a
straight-forward way to mock a DirectBuffer+ByteBuffer combo (lots of final
things there) - and because that code is merely four lines, it seems straight
forward enough as it is.

This commit should be possible to verify the effects of by using an external
tool that lists what regions of files the neo process has memory mapped while
it is under significant load (enough to cause a lot of PWP refreshes, but not
enough to trigger full GC).
So, we could add a volatile field to the buffer to guard properly here, I don't think the memory overhead would be significant (perhaps what, 1-20k or so total). My concern is that adding an always-on assertion on that field will mean performing a volatile read for each read and each write we do to the buffer. I can do some performance testing, but gut feeling is that that will be prohibitively expensive.