浏览代码

send LowMemoryNotification before imposing memory limit, fixes #217

Stefan Siegl 9 年之前
父节点
当前提交
b2eb89e49e
共有 2 个文件被更改,包括 36 次插入16 次删除
  1. 30 15
      v8js_timer.cc
  2. 6 1
      v8js_v8.cc

+ 30 - 15
v8js_timer.cc

@@ -40,27 +40,42 @@ static void v8js_timer_interrupt_handler(v8::Isolate *isolate, void *data) { /*
 
 	v8::Locker locker(isolate);
 	v8::HeapStatistics hs;
-	isolate->GetHeapStatistics(&hs);
+	bool send_notification, has_sent_notification;
 
-	V8JSG(timer_mutex).lock();
+	do {
+		if (send_notification) {
+			isolate->LowMemoryNotification();
+			has_sent_notification = true;
+		}
 
-	for (std::deque< v8js_timer_ctx* >::iterator it = V8JSG(timer_stack).begin();
-		 it != V8JSG(timer_stack).end(); it ++) {
-		v8js_timer_ctx *timer_ctx = *it;
-		v8js_ctx *c = timer_ctx->ctx;
+		isolate->GetHeapStatistics(&hs);
 
-		if(c->isolate != isolate || timer_ctx->killed) {
-			continue;
-		}
+		V8JSG(timer_mutex).lock();
+
+		for (std::deque< v8js_timer_ctx* >::iterator it = V8JSG(timer_stack).begin();
+			 it != V8JSG(timer_stack).end(); it ++) {
+			v8js_timer_ctx *timer_ctx = *it;
+			v8js_ctx *c = timer_ctx->ctx;
 
-		if (timer_ctx->memory_limit > 0 && hs.used_heap_size() > timer_ctx->memory_limit) {
-			timer_ctx->killed = true;
-			v8::V8::TerminateExecution(c->isolate);
-			c->memory_limit_hit = true;
+			if(c->isolate != isolate || timer_ctx->killed) {
+				continue;
+			}
+
+			if (timer_ctx->memory_limit > 0 && hs.used_heap_size() > timer_ctx->memory_limit) {
+				if (has_sent_notification) {
+					timer_ctx->killed = true;
+					v8::V8::TerminateExecution(c->isolate);
+					c->memory_limit_hit = true;
+				} else {
+					// force garbage collection, then check again
+					send_notification = true;
+					break;
+				}
+			}
 		}
-	}
 
-	V8JSG(timer_mutex).unlock();
+		V8JSG(timer_mutex).unlock();
+	} while(send_notification != has_sent_notification);
 }
 /* }}} */
 

+ 6 - 1
v8js_v8.cc

@@ -210,7 +210,12 @@ void v8js_v8_call(v8js_ctx *c, zval **return_value,
 		isolate->GetHeapStatistics(&hs);
 
 		if (hs.used_heap_size() > memory_limit) {
-			c->memory_limit_hit = true;
+			isolate->LowMemoryNotification();
+			isolate->GetHeapStatistics(&hs);
+
+			if (hs.used_heap_size() > memory_limit) {
+				c->memory_limit_hit = true;
+			}
 		}
 	}