Created
November 20, 2012 16:49
-
-
Save purplefox/4119186 to your computer and use it in GitHub Desktop.
Jython Mem leaks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private void cleanUpJythonMess() { | |
try { | |
//Jython stores a reference to the system state on a thread local, when the system state is closed | |
//Jython does not remove the TL so... hey presto a leak | |
//The only way we can remove it is to use reflection to manually remove the tl entry | |
//Nice huh!? | |
//See https://github.com/vert-x/vert.x/issues/417 for more info | |
//Also http://bugs.jython.org/issue1327 | |
Field threadLocalsField = Thread.class.getDeclaredField("threadLocals"); | |
threadLocalsField.setAccessible(true); | |
Class threadLocalMapKlazz = Class.forName("java.lang.ThreadLocal$ThreadLocalMap"); | |
Field tableField = threadLocalMapKlazz.getDeclaredField("table"); | |
tableField.setAccessible(true); | |
Object fieldLocal = threadLocalsField.get(Thread.currentThread()); | |
if (fieldLocal == null) { | |
return; | |
} | |
Object table = tableField.get(fieldLocal); | |
int threadLocalCount = Array.getLength(table); | |
for (int i = 0; i < threadLocalCount; i++) { | |
Object entry = Array.get(table, i); | |
if (entry != null) { | |
Field valueField = entry.getClass().getDeclaredField("value"); | |
valueField.setAccessible(true); | |
Object value = valueField.get(entry); | |
if (value != null) { | |
if (value.getClass().getName().equals("org.python.core.ThreadState")) { | |
valueField.set(entry, null); | |
} | |
} | |
} | |
} | |
//Jython also has another leak in the class org.python.core.codecs | |
//See http://bugs.jython.org/issue1746 | |
//More hackery follows to fix this | |
Class codecsClass = org.python.core.codecs.class; | |
Field searchPathField = codecsClass.getDeclaredField("searchPath"); | |
searchPathField.setAccessible(true); | |
PyList searchPath = (PyList)searchPathField.get(null); | |
if (searchPath != null) { | |
searchPath.clear(); | |
} | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment