Anyway, bookkeeping and reuse of handles is the only way to go, every operating system would be unable to run for a longer time if they never reused values of released file handles. Blowing up the data type for handles only pushes a limit further away but the limit will be reached at some point.
I've thought about using Osiris itself for such book keeping, with basically a DB_RecycledHandle(UUID,handle). You can get the handles even for local objects in Osiris by catching a CharacterItemHandleEvent() (these are triggered even for local objects, and you can send them to CHARACTER:NULL). However, communicating a handle from Osiris back to an item script seems to be impossible. There is no Item/CharacterSetVarItemHandle(), no CharacterItemHandleSetEvent(), and using *SetVarInteger() or *SetVarItem() does not work with handles.
BTW: watch out when dealing with handles for local objects in Osiris. The Divinity Engine crashes with a segmentation fault if you try to do certain things with these handles, presumably because in general it only sees global objects (I forgot the exact code I used, but watch out if you try to reproduce this: if this is done in code that runs automatically when your mod is started, you'll have to remove the offending code using an external editor because the Divinity Engine will immediately crash when loading your mod).
I might have mentioned that earlier somewhere. What we get as an _ItemHandle from queries or 'events' like ItemTemplateAddedToCharacter() is a handle of a complete stack and not of a single item. This might be the reason why there are no GetVar or SetVar calls because a handle does not stand for a single item.
It seems safe to query a string from a handle though because if anything is different in an actual object, it does no longer stack as can be seen with the moonstone at Cyseal North Gate, which has the PUZZLE_HiddenPerception.itemScript attached and does not stack with other moonstones anymore because of this. So I assume getting a String with ItemHandleGetVarString() is safe because all objects on a stack must have identical parameters, including their item scripts, otherwise they would not stack.
Enabling setters is probably possible but you'd have to deal with a lot of stuff if you did id:
Should ALL single items of a stack get this 'event' or just one ? If it was only one, it would have to be moved out of the stack because it was different then which would require creating a new handle for this. Then how would Osiris communicate this new handle to the original caller of the setter ?
There are some Osiris function that can deal with those stacks like for example ItemHandleMoveTo... which has an _Amount parameter and would be better named 'MoveSpecifiedAmountOffTheStackTo...'. If a handle was really a single item there would be no (INTEGER)_Amount but an (INTEGER)_Bool as a parameter, in fact, no additional parameter would really make sense ;-)
For myself I started calling these handles 'handles-of-entities-that-occupy-one-slot' because they represent what can be held in a slot in any container (including our inventories) and not a single item (can be a single one though, and always is for non-stackables like weapons of course).
I have absolutely no idea how bookkeeping of handles in Osiris could help preventing handle overflow when it's the engine that assigns handles, so how would you assign a handle to anything in Osiris ?
(If you meant bookkeeping for some very generic code to prevent it from using unusable handles, it makes more sense to me.)
Anyway, what I meant above was not bookkeping of handles in Osiris but internal bookkeeping of the 'handle generator' Raze was talking about ;-) (That's why I was blabbering about 8k bit fields and such.)
It was all about not only counting up an internal counter - like a sequence in some SQL system - but about doing a 'turnaround and restart from the beginning' once some Max(small) has been reached.
For this to work, bookkeping would have to be done, and could be done with an 8k bit field for 64k handles for example, each bit representing one possible handle value with 1 for used and 0 for free.
That would only work though if handle acquirers would ever release the handles they acquired - inform the generator about the fact that a previously handed out handle is now free to use again. My assumption is, that this releasing of handles never happens in current code and is hard to 'fix' because there might be too many places in the game (and Osiris) code that would have to be changed.
My original curiosity was if a handle could ever be reused internally by the engine when it creates new items. By that I meant the integer value of it, after an item that previously had this value as 'handle' has disappeared for good, I did not mean the item itself. Raze's answer to that was clear: no.
If internal reusability had existed, removal of items (like ItemHandleDelete()) could have helped avoiding the notorious 'crash on zoning'. As it looks, nothing but internal changes to the handle generator (and probably handle users) can help.