Skip to content

Commit b090516

Browse files
HugoBoffinmagreenblatt
authored andcommitted
Fixed several JNI and Java memory leaks (issue chromiumembedded#326)
1 parent 7114114 commit b090516

32 files changed

Lines changed: 287 additions & 75 deletions

java/org/cef/CefClient.java

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,19 @@ public class CefClient extends CefClientHandler
7979
private CefRequestHandler requestHandler_ = null;
8080
private boolean isDisposed_ = false;
8181
private volatile CefBrowser focusedBrowser_ = null;
82+
private final PropertyChangeListener propertyChangeListener = new PropertyChangeListener() {
83+
@Override
84+
public void propertyChange(PropertyChangeEvent evt) {
85+
if (focusedBrowser_ != null) {
86+
Component browserUI = focusedBrowser_.getUIComponent();
87+
Object oldUI = evt.getOldValue();
88+
if (isPartOf(oldUI, browserUI)) {
89+
focusedBrowser_.setFocus(false);
90+
focusedBrowser_ = null;
91+
}
92+
}
93+
}
94+
};
8295

8396
/**
8497
* The CTOR is only accessible within this package.
@@ -89,20 +102,9 @@ public class CefClient extends CefClientHandler
89102
CefClient() throws UnsatisfiedLinkError {
90103
super();
91104

92-
KeyboardFocusManager km = KeyboardFocusManager.getCurrentKeyboardFocusManager();
93-
km.addPropertyChangeListener(new PropertyChangeListener() {
94-
@Override
95-
public void propertyChange(PropertyChangeEvent evt) {
96-
if (focusedBrowser_ != null) {
97-
Component browserUI = focusedBrowser_.getUIComponent();
98-
Object oldUI = evt.getOldValue();
99-
if (isPartOf(oldUI, browserUI)) {
100-
focusedBrowser_.setFocus(false);
101-
focusedBrowser_ = null;
102-
}
103-
}
104-
}
105-
});
105+
KeyboardFocusManager
106+
.getCurrentKeyboardFocusManager()
107+
.addPropertyChangeListener(propertyChangeListener);
106108
}
107109

108110
private boolean isPartOf(Object obj, Component browserUI) {
@@ -554,6 +556,9 @@ private void cleanupBrowser(int identifier) {
554556
}
555557

556558
if (browser_.isEmpty() && isDisposed_) {
559+
KeyboardFocusManager.
560+
getCurrentKeyboardFocusManager()
561+
.removePropertyChangeListener(propertyChangeListener);
557562
removeContextMenuHandler(this);
558563
removeDialogHandler(this);
559564
removeDisplayHandler(this);

java/org/cef/browser/CefBrowserWr.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ public void actionPerformed(ActionEvent e) {
5555
SwingUtilities.invokeLater(new Runnable() {
5656
@Override
5757
public void run() {
58+
if (isClosed())
59+
return;
60+
5861
boolean hasCreatedUI = createBrowserIfRequired(true);
5962

6063
if (hasCreatedUI) {

native/CefCommandLine_N.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,9 @@ Java_org_cef_callback_CefCommandLine_1N_N_1getSwitches(JNIEnv* env,
9191
JNI_CALL_METHOD(env, hashMap, "put",
9292
"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
9393
Object, returnIgn, jkey, jvalue);
94-
UNUSED(returnIgn);
94+
env->DeleteLocalRef(returnIgn);
95+
env->DeleteLocalRef(jkey);
96+
env->DeleteLocalRef(jvalue);
9597
}
9698
return hashMap;
9799
}
@@ -151,6 +153,7 @@ Java_org_cef_callback_CefCommandLine_1N_N_1getArguments(JNIEnv* env,
151153
JNI_CALL_METHOD(env, vector, "add", "(Ljava/lang/object;)Z", Boolean, succ,
152154
argument);
153155
UNUSED(succ);
156+
env->DeleteLocalRef(argument);
154157
}
155158
return vector;
156159
}

native/CefPostData_N.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ Java_org_cef_network_CefPostData_1N_N_1GetElements(JNIEnv* env,
6060
"CefPostDataElement");
6161
JNI_CALL_VOID_METHOD(env, jelements, "addElement", "(Ljava/lang/Object;)V",
6262
jdataElement);
63+
env->DeleteLocalRef(jdataElement);
6364
}
6465
}
6566

native/CefPrintSettings_N.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ Java_org_cef_misc_CefPrintSettings_1N_N_1SetPageRanges(JNIEnv* env,
150150
if (!range)
151151
continue;
152152
rangeList.push_back(GetJNIPageRange(env, range));
153+
env->DeleteLocalRef(range);
153154
}
154155
settings->SetPageRanges(rangeList);
155156
}
@@ -181,6 +182,7 @@ Java_org_cef_misc_CefPrintSettings_1N_N_1GetPageRanges(JNIEnv* env,
181182
jobject range = NewJNIPageRange(env, rangeList.at(i));
182183
JNI_CALL_VOID_METHOD(env, jrangeVector, "addElement",
183184
"(Ljava/lang/Object;)V", range);
185+
env->DeleteLocalRef(range);
184186
}
185187
}
186188

native/CefRequest_N.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,9 @@ Java_org_cef_network_CefRequest_1N_N_1GetHeaderMap(JNIEnv* env,
237237
JNI_CALL_METHOD(env, jheaderMap, "put",
238238
"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
239239
Object, returnIgn, jkey, jvalue);
240-
UNUSED(returnIgn);
240+
env->DeleteLocalRef(returnIgn);
241+
env->DeleteLocalRef(jkey);
242+
env->DeleteLocalRef(jvalue);
241243
}
242244
}
243245

@@ -261,6 +263,7 @@ Java_org_cef_network_CefRequest_1N_N_1SetHeaderMap(JNIEnv* env,
261263
jobject entrySetValues = NULL;
262264
JNI_CALL_METHOD(env, entrySet, "toArray", "()[Ljava/lang/Object;", Object,
263265
entrySetValues);
266+
env->DeleteLocalRef(entrySet);
264267
if (!entrySetValues)
265268
return;
266269

@@ -279,7 +282,11 @@ Java_org_cef_network_CefRequest_1N_N_1SetHeaderMap(JNIEnv* env,
279282
value);
280283
headerMap.insert(std::make_pair(GetJNIString(env, (jstring)key),
281284
GetJNIString(env, (jstring)value)));
285+
env->DeleteLocalRef(key);
286+
env->DeleteLocalRef(value);
287+
env->DeleteLocalRef(mapEntry);
282288
}
289+
env->DeleteLocalRef(entrySetValues);
283290
request->SetHeaderMap(headerMap);
284291
}
285292

native/CefResponse_N.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,9 @@ Java_org_cef_network_CefResponse_1N_N_1GetHeaderMap(JNIEnv* env,
146146
JNI_CALL_METHOD(env, jheaderMap, "put",
147147
"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
148148
Object, returnIgn, jkey, jvalue);
149-
UNUSED(returnIgn);
149+
env->DeleteLocalRef(jkey);
150+
env->DeleteLocalRef(jvalue);
151+
env->DeleteLocalRef(returnIgn);
150152
}
151153
}
152154

@@ -170,6 +172,7 @@ Java_org_cef_network_CefResponse_1N_N_1SetHeaderMap(JNIEnv* env,
170172
jobject entrySetValues = NULL;
171173
JNI_CALL_METHOD(env, entrySet, "toArray", "()[Ljava/lang/Object;", Object,
172174
entrySetValues);
175+
env->DeleteLocalRef(entrySet);
173176
if (!entrySetValues)
174177
return;
175178

@@ -188,7 +191,11 @@ Java_org_cef_network_CefResponse_1N_N_1SetHeaderMap(JNIEnv* env,
188191
value);
189192
headerMap.insert(std::make_pair(GetJNIString(env, (jstring)key),
190193
GetJNIString(env, (jstring)value)));
194+
env->DeleteLocalRef(key);
195+
env->DeleteLocalRef(value);
196+
env->DeleteLocalRef(mapEntry);
191197
}
198+
env->DeleteLocalRef(entrySetValues);
192199
response->SetHeaderMap(headerMap);
193200
}
194201

native/browser_process_handler.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ CefRefPtr<CefPrintHandler> BrowserProcessHandler::GetPrintHandler() {
6666
result = new PrintHandler(env, handler);
6767
SetCefForJNIObject(env, handler, result.get(), "CefPrintHandler");
6868
}
69+
env->DeleteLocalRef(handler);
6970
}
7071
END_ENV(env)
7172
return result;

native/client_handler.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ CefRefPtr<CefContextMenuHandler> ClientHandler::GetContextMenuHandler() {
5858
result = new ContextMenuHandler(env, handler);
5959
SetCefForJNIObject(env, handler, result.get(), "CefContextMenuHandler");
6060
}
61+
env->DeleteLocalRef(handler);
6162
}
6263
END_ENV(env)
6364
return result;
@@ -76,6 +77,7 @@ CefRefPtr<CefDialogHandler> ClientHandler::GetDialogHandler() {
7677
result = new DialogHandler(env, handler);
7778
SetCefForJNIObject(env, handler, result.get(), "CefDialogHandler");
7879
}
80+
env->DeleteLocalRef(handler);
7981
}
8082
END_ENV(env)
8183
return result;
@@ -94,6 +96,7 @@ CefRefPtr<CefDisplayHandler> ClientHandler::GetDisplayHandler() {
9496
result = new DisplayHandler(env, handler);
9597
SetCefForJNIObject(env, handler, result.get(), "CefDisplayHandler");
9698
}
99+
env->DeleteLocalRef(handler);
97100
}
98101
END_ENV(env)
99102
return result;
@@ -112,6 +115,7 @@ CefRefPtr<CefDownloadHandler> ClientHandler::GetDownloadHandler() {
112115
result = new DownloadHandler(env, handler);
113116
SetCefForJNIObject(env, handler, result.get(), "CefDownloadHandler");
114117
}
118+
env->DeleteLocalRef(handler);
115119
}
116120
END_ENV(env)
117121
return result;
@@ -130,6 +134,7 @@ CefRefPtr<CefDragHandler> ClientHandler::GetDragHandler() {
130134
result = new DragHandler(env, handler);
131135
SetCefForJNIObject(env, handler, result.get(), "CefDragHandler");
132136
}
137+
env->DeleteLocalRef(handler);
133138
}
134139
END_ENV(env)
135140
return result;
@@ -148,6 +153,7 @@ CefRefPtr<CefFocusHandler> ClientHandler::GetFocusHandler() {
148153
result = new FocusHandler(env, handler);
149154
SetCefForJNIObject(env, handler, result.get(), "CefFocusHandler");
150155
}
156+
env->DeleteLocalRef(handler);
151157
}
152158
END_ENV(env)
153159
return result;
@@ -166,6 +172,7 @@ CefRefPtr<CefJSDialogHandler> ClientHandler::GetJSDialogHandler() {
166172
result = new JSDialogHandler(env, handler);
167173
SetCefForJNIObject(env, handler, result.get(), "CefJSDialogHandler");
168174
}
175+
env->DeleteLocalRef(handler);
169176
}
170177
END_ENV(env)
171178
return result;
@@ -184,6 +191,7 @@ CefRefPtr<CefKeyboardHandler> ClientHandler::GetKeyboardHandler() {
184191
result = new KeyboardHandler(env, handler);
185192
SetCefForJNIObject(env, handler, result.get(), "CefKeyboardHandler");
186193
}
194+
env->DeleteLocalRef(handler);
187195
}
188196
END_ENV(env)
189197
return result;
@@ -202,6 +210,7 @@ CefRefPtr<CefLifeSpanHandler> ClientHandler::GetLifeSpanHandler() {
202210
result = new LifeSpanHandler(env, handler);
203211
SetCefForJNIObject(env, handler, result.get(), "CefLifeSpanHandler");
204212
}
213+
env->DeleteLocalRef(handler);
205214
}
206215
END_ENV(env)
207216
return result;
@@ -220,6 +229,7 @@ CefRefPtr<CefLoadHandler> ClientHandler::GetLoadHandler() {
220229
result = new LoadHandler(env, handler);
221230
SetCefForJNIObject(env, handler, result.get(), "CefLoadHandler");
222231
}
232+
env->DeleteLocalRef(handler);
223233
}
224234
END_ENV(env)
225235
return result;
@@ -238,6 +248,7 @@ CefRefPtr<CefRenderHandler> ClientHandler::GetRenderHandler() {
238248
result = new RenderHandler(env, handler);
239249
SetCefForJNIObject(env, handler, result.get(), "CefRenderHandler");
240250
}
251+
env->DeleteLocalRef(handler);
241252
}
242253
END_ENV(env)
243254
return result;
@@ -256,6 +267,7 @@ CefRefPtr<CefRequestHandler> ClientHandler::GetRequestHandler() {
256267
result = new RequestHandler(env, handler);
257268
SetCefForJNIObject(env, handler, result.get(), "CefRequestHandler");
258269
}
270+
env->DeleteLocalRef(handler);
259271
}
260272
END_ENV(env)
261273
return result;
@@ -290,6 +302,7 @@ CefRefPtr<WindowHandler> ClientHandler::GetWindowHandler() {
290302
result = new WindowHandler(env, handler);
291303
SetCefForJNIObject(env, handler, result.get(), "WindowHandler");
292304
}
305+
env->DeleteLocalRef(handler);
293306
}
294307
END_ENV(env)
295308
return result;
@@ -328,10 +341,12 @@ void ClientHandler::AddMessageRouter(JNIEnv* env, jobject jmessageRouter) {
328341
jobject jbrowser = env->GetObjectArrayElement(jbrowserArray, i);
329342
CefRefPtr<CefBrowser> browser =
330343
GetCefFromJNIObject<CefBrowser>(env, jbrowser, "CefBrowser");
344+
env->DeleteLocalRef(jbrowser);
331345
if (!browser.get())
332346
continue;
333347
browser->SendProcessMessage(PID_RENDERER, message);
334348
}
349+
env->DeleteLocalRef(jbrowserArray);
335350
}
336351

337352
void ClientHandler::RemoveMessageRouter(JNIEnv* env, jobject jmessageRouter) {
@@ -367,10 +382,12 @@ void ClientHandler::RemoveMessageRouter(JNIEnv* env, jobject jmessageRouter) {
367382
jobject jbrowser = env->GetObjectArrayElement(jbrowserArray, i);
368383
CefRefPtr<CefBrowser> browser =
369384
GetCefFromJNIObject<CefBrowser>(env, jbrowser, "CefBrowser");
385+
env->DeleteLocalRef(jbrowser);
370386
if (!browser.get())
371387
continue;
372388
browser->SendProcessMessage(PID_RENDERER, message);
373389
}
390+
env->DeleteLocalRef(jbrowserArray);
374391
}
375392

376393
void ClientHandler::OnAfterCreated() {}

native/context.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ bool Context::PreInitialize(JNIEnv* env, jobject c) {
5959
if (!javaClassLoader)
6060
return false;
6161
SetJavaClassLoader(env, javaClassLoader);
62+
env->DeleteLocalRef(javaClassLoader);
6263

6364
return true;
6465
}

0 commit comments

Comments
 (0)