Some time ago in the project using Ehcache do cache, due to the large amount of data I would like to increase the diskspoolbuffersizemb to improve the Ehcache storage speed, the result is increased to 2GB above, ehcache into the speed becomes unusually slow, Search on the internet for a long time also did not find the reason, today finally found the reason. Because the diskspoolbuffersizemb is actually in bytes, the 2GB has exceeded the range of positive integer representations, causing Diskspoolbuffersizemb to be negative, and Ehcache mistakenly assumed that the disk cache queue is full when put. Each time you perform a pause of 50ms,.
In the Diskstoragefactory class
Java code//calculation Queue Size spoolbuffersize*1024*1024 Note there is no positive integer overflow judgment this.queuecapacity = Cache.getcacheconfiguration (). getdisks POOLBUFFERSIZEMB () * megabyte; Determines whether the cache is full public boolean bufferfull () {//If a positive integer overflow occurs, this always returns true, and the cached full return is False (Diskqueue.size () * elementsize) > queuecapacity; }
There's a judge in the cache. Disk cache is full, if full sleep for a short period of time the default is 50 milliseconds to execute, slowing down the production line
Java code /** * wait outside of synchronized block so as not to block readers * if the disk store spool is full wait a short time to give it a chance to * catch up. * todo maybe provide a warning if this is continually happening or monitor via JMX */ private void backoffifdiskspoolfull () { if ( Compoundstore.bufferfull ()) { // call Diskstoragefactory Bufferfull method // back off to avoid outofmemoryerror try { thread.sleep (BACK_OFF_TIME_MILLIS); } catch ( Interruptedexception e) { thread.currentthread () interrupt (); } } }
In the cache class, each put method calls the Backoffifdiskspoolfull method, and the code for the internal put method is
Java Code private void Putinternal (element element, Boolean donotnotifycachereplicators, Boolean usecachewriter) { 。。。。。 Applydefaultstoelementwithoutlifespanset (Element); Backoffifdiskspoolfull (); Execution whether suspend element.updateupdatestatistics (); 。。。。。 }
This could be an integer overflow check that Ehcache developers are missing, Diskspoolbuffersizemb configured to have a negative number of 2gb,queuecapacity, and pauses 50ms each time the element is placed, causing the speed to be unusually slow. The default value of the general situation can meet the requirements do not need to adjust the size of the DISKSPOOLBUFFERSIZEMB.
Diskspoolbuffersizemb an explanation of official stability.
DISKSPOOLBUFFERSIZEMB:
This is the size to allocate the diskstore for a spool buffer. Writes are made
To the and then asynchronously written to disk. The default size is 30MB.
Each spool-used is the cache. If you have outofmemory errors consider
Lowering this value. To improve Diskstore performance consider increasing it. Trace level
Logging in the Diskstore would show if put back ups are occurring.