package Libraries.Utils.ReleaseVariable; import java.lang.reflect.*; import java.util.*; import java.util.concurrent.atomic.*; import java.io.*; import org.xml.sax.InputSource; import com.tibco.xml.datamodel.XiNode; import com.tibco.xml.datamodel.XiParserFactory; import com.tibco.xml.xdata.xpath.Variable; import com.tibco.xml.xdata.xpath.VariableList; import com.tibco.pe.core.*; public class ReleaseVariableJavaCode{ public static JobPool getJobPool() { for (Field f : Engine.class.getDeclaredFields()) { if (f.getType().getName().endsWith("JobPool")) { f.setAccessible(true); try { return (JobPool) f.get(null); } catch (Throwable te) { throw new RuntimeException("Cannot access JobPool: "+te.getMessage(), te); } } } throw new RuntimeException("Cannot access JobPool"); } public static long[] getJobIds() { try { return getJobPool().getJobIds(); } catch (Throwable t) { throw new RuntimeException("Cannot access JobPool.getJobIds(): "+t.getMessage(), t); } } public static VariableList getJobVariables(long jid, int trackId) { try { Method getAttributes = Class.forName("com.tibco.pe.core.Job").getDeclaredMethod("getAttributes", new Class<?>[] { int.class }); getAttributes.setAccessible(true); return (VariableList) getAttributes.invoke(getJobPool().findJob(jid), trackId); } catch (Throwable t) { throw new RuntimeException("Cannot access job variables: "+t.getMessage(), t); } } public int getTrackId(long jid) { try { Method getter = Class.forName("com.tibco.pe.core.Job").getDeclaredMethod("getTrackId", new Class<?>[0]); getter.setAccessible(true); return (int) getter.invoke(getJobPool().findJob(jid)); } catch (Throwable t) { throw new RuntimeException("Cannot access job methods: "+t.getMessage(), t); } } public void nullifyXiNode(XiNode node) { while (node!=null && node.hasChildNodes()) node.removeChild(node.getLastChild()); if (callGC==1) System.gc(); } public void prune(XiNode node, String[] tokens, int i) { //System.out.println("prune at level "+i+" of "+node); if (i==1) node = node.hasChildNodes() ? node.getFirstChild() : null; // root node while (node!=null) { //System.out.println("node name is "+(node.getName()!=null ? node.getName().getLocalName() : null)); if (node.getName() != null && tokens[i].equals(node.getName().getLocalName())) { if (i == tokens.length-1) { //System.out.println("nullify"); nullifyXiNode( node ); } else { XiNode nd = node.hasChildNodes() ? node.getFirstChild() : null; if (nd!=null) { prune(nd, tokens, i+1); } } } node = node.hasNextSibling() ? node.getNextSibling() : null; } } /****** START SET/GET METHOD, DO NOT MODIFY *****/ protected long jobId = 0; protected String var = ""; protected int callGC = 0; public long getjobId() { return jobId; } public void setjobId(long val) { jobId = val; } public String getvar() { return var; } public void setvar(String val) { var = val; } public int getcallGC() { return callGC; } public void setcallGC(int val) { callGC = val; } /****** END SET/GET METHOD, DO NOT MODIFY *****/ public ReleaseVariableJavaCode() { } public void invoke() throws Exception { /* Available Variables: DO NOT MODIFY In : long jobId In : String var In : int callGC * Available Variables: DO NOT MODIFY *****/ String[] tokens = var.split("/"); int currentTrackId = getTrackId(jobId); for (int iter=0; iter <= 4; iter++) { VariableList varList = getJobVariables(jobId, iter); Variable v = varList!=null && iter != currentTrackId ? varList.getVariable(tokens[0]) : null; if (v!=null) { if (tokens.length == 1) { nullifyXiNode( v.getValue() ); } else if (tokens.length>1) { prune( v.getValue(), tokens, 1); } } } } }
wtorek, lutego 24, 2015
How to release unused XiNodes from BW process variables
BW accumulates variables across job lifetime. Very often intermediate variables in later steps are not needed any more, but still occupy memory. It is possible to clean them and make more memory for new jobs, globally reducing RAM requirement for whole BW instance.
Subskrybuj:
Komentarze do posta (Atom)
0 komentarze:
Prześlij komentarz