关于垃圾回收(内存管理)的一点疑问

badguy2002 2006-08-12 07:35:35
import javax.swing.*;
import java.awt.event.*;
import java.awt.FlowLayout;
import java.awt.Dimension;
import java.lang.String;
import javax.swing.JOptionPane;
import java.awt.Container;
import java.util.Hashtable;
import java.awt.BorderLayout;
import java.awt.Component;
import javax.swing.DefaultListCellRenderer;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
class ComboBoxRenderer
implements ListCellRenderer {

public ComboBoxRenderer() {
}

public Component getListCellRendererComponent(
JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
JLabel itemLabel = new JLabel(value);
JPanel itemPanel = new JPanel();
itemPanel.setToolTipText(sValue);
itemPanel.setSize(list.getSize().width, 25);
itemPanel.setLayout(new BorderLayout());
itemPanel.add(itemLabel, BorderLayout.WEST);
if (isSelected || cellHasFocus) {
itemPanel.setForeground(list.getSelectionForeground());
itemPanel.setBackground(list.getSelectionBackground());
}
else {
itemPanel.setForeground(list.getForeground());
itemPanel.setBackground(list.getBackground());
}
return itemPanel;
}
}
public class test extends JFrame{
JComboBox select=null;
JButton button=null;
consuMem mem=null;
String preItem=null;
Hashtable sessionTable=new Hashtable();
public test(String title) {
super(title);
setSize(new Dimension(200,100));
getContentPane().setLayout(new FlowLayout());
addWindowListener(
new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}

});
select=new JComboBox();
select.setRenderer(
new ComboBoxRenderer(ComboBoxRenderer.COMBOTYPE_TEMPLATE));
for (int i=0;i<200;i++) {
select.addItem(String.valueOf(i));
}
select.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){

}
});
getContentPane().add(select);

}
public static void main(String[] args) {
sessionWindow swindow=null;
test test1=new test("MainWindow");
test1.show();
}
}
以上程序主要是自己实现一个ListCellRenderer类,调试,用键盘在combobox的item中反复上下切换,观察内存继续增长,怀疑是 JLabel itemLabel = new JLabel(value);
JPanel itemPanel = new JPanel();
这两句的问题,因为它们每次都会分配新的对象,于是将ComboBoxRenderer类改为如下形式:
class ComboBoxRenderer
implements ListCellRenderer {
public static JLabel itemLabel = new JLabel();
public static JPanel itemPanel = new JPanel();
private int type_;

public ComboBoxRenderer(int type) {

}

public Component getListCellRendererComponent(
JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
if (value == null) {
return null;
}
itemLabel.setText(value);
itemPanel.setToolTipText(sValue);
itemPanel.setSize(list.getSize().width, 25);
itemPanel.setLayout(new BorderLayout());
itemPanel.add(itemLabel, BorderLayout.WEST);
if (isSelected || cellHasFocus) {
itemPanel.setForeground(list.getSelectionForeground());
itemPanel.setBackground(list.getSelectionBackground());
}
else {
itemPanel.setForeground(list.getForeground());
itemPanel.setBackground(list.getBackground());
}
return itemPanel;
}
}
发现不会出现上面的现象了。但是我不大理解为什么会这样,按道理说,JVM每次getListCellRendererComponent()绘制完后,对它们的引用就会消失,内存也会被回收,为什么会出现上面的现象内,哪位大侠能够给解释一下,谢谢了
...全文
172 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
badguy2002 2006-08-13
  • 打赏
  • 举报
回复
但是隔一段时间是多长呢?我等了很长时间也没有见回收啊
我的理解是,对ListCellRender是不是根本就不回收。
也就是说
1.MainFrame中Combox初始化时,会调用getListCellRenderer()获取combox item的render进行绘制(最典型的就是renderer是JLabel的一个子类),
2.当用户选择combox出现下拉框时,也会调用此方法进行绘制
3.当combox失去焦点时,绘制完成的JLabel只是隐藏(或者被其他的component所覆盖),而不是被dispose,所以不会被回收,否则根本无法解释上面的代码会出现OutOfMemory Error.

还望GUI高手给解释解释啊,谢谢了
gtlang78 2006-08-12
  • 打赏
  • 举报
回复
jvm 隔一段时间才作一次GC, 所以引用释放之后,对象所占的内存不会马上释放掉。

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧