From d05f94afa50b56d12883ab0f21203fc5cc187c35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=F8=EDk?= Date: Fri, 19 Jul 2013 11:42:56 +0200 Subject: [PATCH] Issue #248 Freeing memory before loading new file --- .../com/jpexs/decompiler/flash/gui/Freed.java | 26 ++++++++ .../com/jpexs/decompiler/flash/gui/Main.java | 5 ++ .../jpexs/decompiler/flash/gui/MainFrame.java | 60 +++---------------- .../decompiler/flash/gui/abc/ABCPanel.java | 14 +++-- .../decompiler/flash/helpers/Helper.java | 25 ++++++++ 5 files changed, 75 insertions(+), 55 deletions(-) create mode 100644 trunk/src/com/jpexs/decompiler/flash/gui/Freed.java diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/Freed.java b/trunk/src/com/jpexs/decompiler/flash/gui/Freed.java new file mode 100644 index 000000000..03fd694cc --- /dev/null +++ b/trunk/src/com/jpexs/decompiler/flash/gui/Freed.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2010-2013 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.jpexs.decompiler.flash.gui; + +/** + * + * @author JPEXS + */ +public interface Freed { + + public void free(); +} diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/Main.java b/trunk/src/com/jpexs/decompiler/flash/gui/Main.java index 6e30ff80b..82aecee28 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/Main.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/Main.java @@ -252,6 +252,11 @@ public class Main { public static boolean openFile(String swfFile) { if (mainFrame != null) { mainFrame.setVisible(false); + Helper.emptyObject(mainFrame); + swf = null; + mainFrame = null; + Cache.clearAll(); + System.gc(); } Main.file = swfFile; if (Main.loadingDialog == null) { diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java index 4d0ae6e57..98e4820ce 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/MainFrame.java @@ -185,7 +185,7 @@ import javax.swing.tree.TreeSelectionModel; * * @author Jindra */ -public class MainFrame extends AppFrame implements ActionListener, TreeSelectionListener { +public class MainFrame extends AppFrame implements ActionListener, TreeSelectionListener, Freed { private SWF swf; public ABCPanel abcPanel; @@ -422,11 +422,6 @@ public class MainFrame extends AppFrame implements ActionListener, TreeSelection autoDeobfuscateMenuItem.addActionListener(this); autoDeobfuscateMenuItem.setActionCommand("AUTODEOBFUSCATE"); - - /* JCheckBoxMenuItem miSubLimiter = new JCheckBoxMenuItem("Enable sub limiter"); - miSubLimiter.setActionCommand("SUBLIMITER"); - miSubLimiter.addActionListener(this); - */ JMenuItem miRenameOneIdentifier = new JMenuItem(translate("menu.tools.deobfuscation.globalrename")); miRenameOneIdentifier.setActionCommand("RENAMEONEIDENTIFIER"); miRenameOneIdentifier.addActionListener(this); @@ -435,43 +430,10 @@ public class MainFrame extends AppFrame implements ActionListener, TreeSelection miRenameIdentifiers.setActionCommand("RENAMEIDENTIFIERS"); miRenameIdentifiers.addActionListener(this); - /*JMenuItem miRemoveDeadCode = new JMenuItem("Remove dead code"); - miRemoveDeadCode.setActionCommand("REMOVEDEADCODE"); - miRemoveDeadCode.addActionListener(this); - - JMenuItem miRemoveDeadCodeAll = new JMenuItem("Remove all dead code"); - miRemoveDeadCodeAll.setActionCommand("REMOVEDEADCODEALL"); - miRemoveDeadCodeAll.addActionListener(this); - - JMenuItem miTraps = new JMenuItem("Remove traps"); - miTraps.setActionCommand("REMOVETRAPS"); - miTraps.addActionListener(this); - - JMenuItem miTrapsAll = new JMenuItem("Remove all traps"); - miTrapsAll.setActionCommand("REMOVETRAPSALL"); - miTrapsAll.addActionListener(this); - - JMenuItem miControlFlow = new JMenuItem("Restore control flow"); - miControlFlow.setActionCommand("RESTORECONTROLFLOW"); - miControlFlow.addActionListener(this); - - JMenuItem miControlFlowAll = new JMenuItem("Restore all control flow"); - miControlFlowAll.setActionCommand("RESTORECONTROLFLOWALL"); - miControlFlowAll.addActionListener(this);*/ menuDeobfuscation.add(miRenameOneIdentifier); menuDeobfuscation.add(miRenameIdentifiers); - //menuDeobfuscation.add(miSubLimiter); menuDeobfuscation.add(miDeobfuscation); - /*menuDeobfuscation.add(miDeobfuscate); - menuDeobfuscation.addSeparator();*/ - /*menuDeobfuscation.add(miRemoveDeadCode); - menuDeobfuscation.add(miRemoveDeadCodeAll); - menuDeobfuscation.add(miTraps); - menuDeobfuscation.add(miTrapsAll); - menuDeobfuscation.add(miControlFlow); - menuDeobfuscation.add(miControlFlowAll); - */ JMenu menuTools = new JMenu(translate("menu.tools")); JMenuItem miProxy = new JMenuItem(translate("menu.tools.proxy")); miProxy.setActionCommand("SHOWPROXY"); @@ -580,6 +542,7 @@ public class MainFrame extends AppFrame implements ActionListener, TreeSelection menuBar.add(menuHelp); setJMenuBar(menuBar); + List objs = new ArrayList<>(); objs.addAll(swf.tags); @@ -806,17 +769,6 @@ public class MainFrame extends AppFrame implements ActionListener, TreeSelection textValue.setEditable(false); //textValue.setFont(UIManager.getFont("TextField.font")); - /*JPanel textBottomPanel = new JPanel(); - textBottomPanel.setLayout(new BoxLayout(textBottomPanel, BoxLayout.X_AXIS)); - textBottomPanel.add(new JLabel("Xmin:")); - textBottomPanel.add(textRectXmin); - textBottomPanel.add(new JLabel("Ymin:")); - textBottomPanel.add(textRectYmin); - textBottomPanel.add(new JLabel("Xmax:")); - textBottomPanel.add(textRectXmax); - textBottomPanel.add(new JLabel("Ymax:")); - textBottomPanel.add(textRectYmax);*/ - JPanel textButtonsPanel = new JPanel(); @@ -1112,6 +1064,7 @@ public class MainFrame extends AppFrame implements ActionListener, TreeSelection } } }); + View.centerScreen(this); tagTree.addKeyListener(new KeyAdapter() { @Override @@ -1592,7 +1545,7 @@ public class MainFrame extends AppFrame implements ActionListener, TreeSelection TagNode tti = new TagNode(t); if (((Container) t).getItemCount() > 0) { List subItems = ((Container) t).getSubItems(); - tti.subItems = createTagList(subItems, parent); + tti.subItems = createTagList(subItems, t); } //ret.add(tti); } @@ -2720,4 +2673,9 @@ public class MainFrame extends AppFrame implements ActionListener, TreeSelection reload(true); } } + + @Override + public void free() { + Helper.emptyObject(this); + } } diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java index 343b74529..d996cf3e4 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java @@ -22,6 +22,7 @@ import com.jpexs.decompiler.flash.abc.ABC; import com.jpexs.decompiler.flash.abc.ClassPath; import com.jpexs.decompiler.flash.abc.ScriptPack; import static com.jpexs.decompiler.flash.gui.AppStrings.translate; +import com.jpexs.decompiler.flash.gui.Freed; import com.jpexs.decompiler.flash.gui.Main; import com.jpexs.decompiler.flash.gui.TagTreeModel; import com.jpexs.decompiler.flash.gui.View; @@ -33,6 +34,7 @@ import com.jpexs.decompiler.flash.gui.abc.tablemodels.NamespaceSetTableModel; import com.jpexs.decompiler.flash.gui.abc.tablemodels.NamespaceTableModel; import com.jpexs.decompiler.flash.gui.abc.tablemodels.StringTableModel; import com.jpexs.decompiler.flash.gui.abc.tablemodels.UIntTableModel; +import com.jpexs.decompiler.flash.helpers.Helper; import com.jpexs.decompiler.flash.helpers.collections.MyEntry; import com.jpexs.decompiler.flash.tags.ABCContainerTag; import java.awt.BorderLayout; @@ -57,7 +59,7 @@ import javax.swing.tree.TreePath; import jsyntaxpane.DefaultSyntaxKit; import jsyntaxpane.actions.DocumentSearchData; -public class ABCPanel extends JPanel implements ItemListener, ActionListener { +public class ABCPanel extends JPanel implements ItemListener, ActionListener, Freed { public TraitsList navigator; public ClassesListTree classTree; @@ -75,7 +77,7 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener { public JLabel asmLabel = new JLabel(translate("panel.disassembled")); public JLabel decLabel = new JLabel(translate("panel.decompiled")); public DetailPanel detailPanel; - public JTextField filterField = new JTextField(""); + public JTextField filterField = new JTextField(); public JPanel navPanel; public JTabbedPane tabbedPane; public JPanel searchPanel; @@ -247,10 +249,13 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener { } + @Override + public void free() { + Helper.emptyObject(this); + } + @SuppressWarnings("unchecked") public ABCPanel(List list, SWF swf) { - - DefaultSyntaxKit.initKit(); this.list = list; @@ -357,6 +362,7 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener { prevSearchButton.setMargin(new Insets(3, 3, 3, 3)); prevSearchButton.addActionListener(this); prevSearchButton.setActionCommand("SEARCHPREV"); + JButton nextSearchButton = new JButton(View.getIcon("next16")); nextSearchButton.setMargin(new Insets(3, 3, 3, 3)); nextSearchButton.addActionListener(this); diff --git a/trunk/src/com/jpexs/decompiler/flash/helpers/Helper.java b/trunk/src/com/jpexs/decompiler/flash/helpers/Helper.java index fdbdb2a3f..29a9b187e 100644 --- a/trunk/src/com/jpexs/decompiler/flash/helpers/Helper.java +++ b/trunk/src/com/jpexs/decompiler/flash/helpers/Helper.java @@ -16,7 +16,9 @@ */ package com.jpexs.decompiler.flash.helpers; +import com.jpexs.decompiler.flash.gui.Freed; import com.jpexs.decompiler.graph.GraphTargetItem; +import java.awt.Component; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; @@ -26,8 +28,10 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.UnsupportedEncodingException; +import java.lang.reflect.Field; import java.util.ArrayList; import java.util.BitSet; +import java.util.Collection; import java.util.List; import java.util.Stack; import java.util.logging.Level; @@ -456,4 +460,25 @@ public class Helper { } return sn; } + + public static void emptyObject(Object obj) { + Field[] fields = obj.getClass().getDeclaredFields(); + for (Field f : fields) { + try { + f.setAccessible(true); + Object v = f.get(obj); + if (v instanceof Collection) { + ((Collection) v).clear(); + } + if (v instanceof Component) { + ((Component) v).getParent().remove((Component) v); + } + if (v instanceof Freed) { + ((Freed) v).free(); + } + f.set(obj, null); + } catch (Exception ex) { + } + } + } }