I have a service which stages all calls made to it in memory, because we don't want to lose the data and at the same time we need this service to ever fail due to any external dependency (like a DB for example). These staged calls are then routinely picked up and processed in the background.
If, for any reason, if there are too many calls and we run out of memory, we need to be alarmed.
So, the question simply put, is this: What exception do I need to catch or monitor on to notify me when an addition to a list fails due to insufficient resources? Will it result in an OOM in the VM itself, or is there a collection-level limit as well?
If there is no collection-level limit, how would you recommend I monitor the usage of the service? Currently, we have heap usage and memory usage metrics. Are those enough? Also, the JVMs are configured to kill on an OOM error (this is because the VM manager then restarts any process it is managing on a kill).
解决方案
The exception to be thrown is OutOfMemoryException. This exception can be thrown in any part of your application, once your collection eats all available heap space.
However if you know that it can be potentially thrown for a specific collection, the best way might be to prevent this to happen, i.e. cap this collection or use caching, so that unused entities are evicted and reloaded on demand. For a lightweight cache implementation I would recommend Guava's CacheBuilder.
UPDATE
Since everybody suggests FS-based storage, here is my lightweight drop-in proposal:
CacheBuilder to load your serialized data from NoSQL DB
Kryo serializer to convert your objects into byte[]
MapDB to store (or any other embedded NoSQL solution you prefer).