@@ -267,6 +267,8 @@ struct _zend_mm_heap {
267
267
int peak_chunks_count ; /* peak number of allocated chunks for current request */
268
268
int cached_chunks_count ; /* number of cached chunks */
269
269
double avg_chunks_count ; /* average number of chunks allocated per request */
270
+ int last_chunks_delete_boundary ; /* numer of chunks after last deletion */
271
+ int last_chunks_delete_count ; /* number of deletion over the last boundary */
270
272
#if ZEND_MM_CUSTOM
271
273
union {
272
274
struct {
@@ -1122,7 +1124,9 @@ static zend_always_inline void zend_mm_delete_chunk(zend_mm_heap *heap, zend_mm_
1122
1124
chunk -> next -> prev = chunk -> prev ;
1123
1125
chunk -> prev -> next = chunk -> next ;
1124
1126
heap -> chunks_count -- ;
1125
- if (heap -> chunks_count + heap -> cached_chunks_count < heap -> avg_chunks_count + 0.1 ) {
1127
+ if (heap -> chunks_count + heap -> cached_chunks_count < heap -> avg_chunks_count + 0.1
1128
+ || (heap -> chunks_count == heap -> last_chunks_delete_boundary
1129
+ && heap -> last_chunks_delete_count >= 4 )) {
1126
1130
/* delay deletion */
1127
1131
heap -> cached_chunks_count ++ ;
1128
1132
chunk -> next = heap -> cached_chunks ;
@@ -1131,6 +1135,14 @@ static zend_always_inline void zend_mm_delete_chunk(zend_mm_heap *heap, zend_mm_
1131
1135
#if ZEND_MM_STAT || ZEND_MM_LIMIT
1132
1136
heap -> real_size -= ZEND_MM_CHUNK_SIZE ;
1133
1137
#endif
1138
+ if (!heap -> cached_chunks ) {
1139
+ if (heap -> chunks_count != heap -> last_chunks_delete_boundary ) {
1140
+ heap -> last_chunks_delete_boundary = heap -> chunks_count ;
1141
+ heap -> last_chunks_delete_count = 0 ;
1142
+ } else {
1143
+ heap -> last_chunks_delete_count ++ ;
1144
+ }
1145
+ }
1134
1146
if (!heap -> cached_chunks || chunk -> num > heap -> cached_chunks -> num ) {
1135
1147
zend_mm_chunk_free (heap , chunk , ZEND_MM_CHUNK_SIZE );
1136
1148
} else {
@@ -1864,6 +1876,8 @@ static zend_mm_heap *zend_mm_init(void)
1864
1876
heap -> peak_chunks_count = 1 ;
1865
1877
heap -> cached_chunks_count = 0 ;
1866
1878
heap -> avg_chunks_count = 1.0 ;
1879
+ heap -> last_chunks_delete_boundary = 0 ;
1880
+ heap -> last_chunks_delete_count = 0 ;
1867
1881
#if ZEND_MM_STAT || ZEND_MM_LIMIT
1868
1882
heap -> real_size = ZEND_MM_CHUNK_SIZE ;
1869
1883
#endif
@@ -2279,6 +2293,8 @@ void zend_mm_shutdown(zend_mm_heap *heap, int full, int silent)
2279
2293
p -> map [0 ] = ZEND_MM_LRUN (ZEND_MM_FIRST_PAGE );
2280
2294
heap -> chunks_count = 1 ;
2281
2295
heap -> peak_chunks_count = 1 ;
2296
+ heap -> last_chunks_delete_boundary = 0 ;
2297
+ heap -> last_chunks_delete_count = 0 ;
2282
2298
#if ZEND_MM_STAT || ZEND_MM_LIMIT
2283
2299
heap -> real_size = ZEND_MM_CHUNK_SIZE ;
2284
2300
#endif
@@ -2811,6 +2827,8 @@ ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_handlers *handlers, void
2811
2827
heap -> peak_chunks_count = 1 ;
2812
2828
heap -> cached_chunks_count = 0 ;
2813
2829
heap -> avg_chunks_count = 1.0 ;
2830
+ heap -> last_chunks_delete_boundary = 0 ;
2831
+ heap -> last_chunks_delete_count = 0 ;
2814
2832
#if ZEND_MM_STAT || ZEND_MM_LIMIT
2815
2833
heap -> real_size = ZEND_MM_CHUNK_SIZE ;
2816
2834
#endif
0 commit comments