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).