-
-
Save Kurukshetran/c0e0c73eb2fb0f0fd9c5ecd6c3f1534a to your computer and use it in GitHub Desktop.
Jython Mem leaks
This file contains hidden or 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