Java内存泄漏
private boolean refreshResponseWindow(MessageObject message) {
this.responsePanel.removeAll();
this.responsePanel.add(message.buildGUI());
this.responsePanel.validate();
message = null;
return true;
}
正在发生的问题是当我收到越来越多的消息时,我的Java程序的内存使用量继续增长,最终导致其锁定。我已将内存泄漏隔离到上面的代码,特别是添加过程调用。我假设removeAll会清除我面板的内容,但它似乎仍在继续增长。
注意:message.buildGUI()返回一个显示在responsePanel上的JPanel
跟进:
BuildGUI代码如此显示
public JPanel buildGUI() throws Exception {
JPanel busPanel = new JPanel();
busPanel.setLayout(new GridBagLayout());
busPanel.setPreferredSize(new Dimension(Globals.panelW, Globals.panelH));
busPanel.setMinimumSize(new Dimension(Globals.panelW, Globals.panelH));
final JLabel headingLabel = new JLabel();
headingLabel.setFont(new Font("", Font.PLAIN, 18));
headingLabel.setText(this.name);
final GridBagConstraints gridBagConstraints_heading = new GridBagConstraints();
gridBagConstraints_heading.gridwidth = 2;
gridBagConstraints_heading.gridy = 0;
gridBagConstraints_heading.gridx = 0;
busPanel.add(headingLabel, gridBagConstraints_heading);
//Many more gui components marked as final
return busPanel;
没有监听器,返回的面板仅用于显示目的。
答案 0 :(得分:5)
buildGUI
方法是否为您的业务对象添加了侦听器?这是内存泄漏的常见原因。调用responsePanel.removeAll()
将删除组件,但组件仍可能在responsePanel
或其他对象上注册为侦听器,从而导致它们保留在内存中。
答案 1 :(得分:1)
这是解决removeAll()内存泄漏问题的 A 解决方案...
我称之为组件毁灭。
效率不高,除非你真的需要,否则我不建议使用它
可以通过指定要查找的侦听器类型加快速度。
注意:它会从面板中删除LayoutManager,因此您需要重新添加它。
使用示例:
Utils.annihilateComponent(myJPanel,null,null); // This is slow if myJPanel has many components
myJpanel.setLayout(new FlowLayout());
Utils.annihilateComponent(myJPanel,new String[]{"Action","Mouse","PopupMenu"},new String[]{"java.awt.event.","javax.swing.event."});
myJPanel.setLayout(new MigLayout());
myJPanel.add(new JLabel("Once you start using MigLayout you'll never look back"),"wrap");
//In an JDialog:
private void formWindowClosing(java.awt.event.WindowEvent evt) {
Utils.annihilateComponent(this);
}
以下是代码:
import java.awt.*;
import java.lang.reflect.Method;
import java.util.EventListener;
public class Utils {
private static String[] allPackages = { "java.awt.event.","javax.swing.event.","java.beans.","java.beans.beancontext."
,"java.awt.dnd.","javax.sql.","javax.naming.event.","javax.imageio.event.","javax.net.ssl.","javax.sound.midi."
,"javax.naming.ldap.","java.util.prefs.","javax.sound.sampled." };
public static void removeListeners (Object o, String listenerName, String[] packages) {
Class oc = o.getClass();
try {
Method getListenersMethod = oc.getMethod("get"+listenerName+"Listeners",(Class[])null);
String[] p;
if (packages == null) {
p = allPackages;
} else {
p = packages;
}
// Find the listener Class
Class listenerClass = null;
int pIndex = 0;
while (listenerClass == null && pIndex < p.length) {
try {
listenerClass = Class.forName(p[pIndex]+listenerName+"Listener");
} catch (Exception ex) {
/* Ignore */
}
pIndex++;
}
if (listenerClass == null) {
return; // Couldn't find the class for this listener type
}
Method removeListenerMethod = oc.getMethod("remove"+listenerName+"Listener", new Class[] { listenerClass });
if (getListenersMethod != null) {
//res1 = m.invoke(dto1,(Object[])null);
Object els = getListenersMethod.invoke(o,(Object[])null);
if (els instanceof EventListener[]) {
EventListener[] listeners = (EventListener[])els;
for (int i = 0; i < listeners.length; i++) {
removeListenerMethod.invoke(o, new Object[] { listeners[i] });
}
}
}
} catch (Exception e) {
// Ignore
}
}
private static String[] allListeners = { "Action","Adjustment","Ancestor","AWTEvent","BeanContextMembership","BeanContextServiceRevoked"
,"BeanContextServices","Caret","CellEditor","Change","Component","ConnectionEvent","Container","ControllerEvent"
,"Document","DragGesture","DragSource","DragSourceMotion","DropTarget","Focus","HandshakeCompleted","HierarchyBounds"
,"Hierarchy","Hyperlink","IIOReadProgress","IIOReadUpdate","IIOReadWarning","IIOWriteProgress","IIOWriteWarning"
,"InputMethod","InternalFrame","Item","Key","Line","ListData","ListSelection","MenuDragMouse","MenuKey","Menu"
,"MetaEvent","MouseInput","Mouse","MouseMotion","MouseWheel","NamespaceChange","Naming","NodeChange","ObjectChange"
,"PopupMenu","PreferenceChange","PropertyChange","RowSet","SSLSessionBinding","TableColumnModel","TableModel"
,"Text","TreeExpansion","TreeModel","TreeSelection","TreeWillExpand","UndoableEdit","UnsolicitedNotification"
,"VetoableChange","WindowFocus","Window","WindowState" } ;
public static void removeAllListeners(Component c, String[] listeners, String[] packages) {
String[] l;
if (listeners == null) {
l = allListeners;
} else {
l = listeners;
}
for (int i = 0; i < l.length; i++) {
removeListeners(c,l[i],packages);
}
}
public static void annihilateComponent(Object o, String[] listeners, String[] packages) {
if (o == null) {
return;
}
if (o instanceof Container) {
Component[] c = ((Container)o).getComponents();
for (int i = 0; i < c.length; i++) {
annihilateComponent(c[i],listeners,packages);
}
((Container)o).setLayout(null);
((Container)o).setFocusTraversalPolicy(null);
((Container)o).removeAll();
}
if (o instanceof javax.swing.JScrollPane) {
((javax.swing.JScrollPane)o).setViewportView(null);
}
if (o instanceof Component) {
removeAllListeners((Component)o,listeners,packages);
}
if (o instanceof Window) {
((Window)o).dispose();
}
}
public static void annihilateComponent(Object o) {
annihilateComponent(o,null,null);
}
}