⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 recycle.java

📁 实现可变分区分配与回收
💻 JAVA
字号:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/*
 *
 * 课题:存储管理——动态分区分配算法的模拟:
 * 
 */
//回收算法界面
public class Recycle extends JFrame implements ActionListener, ItemListener {

	mem[] m;
	ImageIcon p = new ImageIcon("tx_002.png");// 用于作为标题栏图标
	JTextPane t = new JTextPane();
	JPanel p1 = new JPanel();
	JPanel p2 = new JPanel();
	JScrollPane sp = new JScrollPane(t);
	JButton b = new JButton("生成内存状态");
	JButton b2 = new JButton("回收");
	JComboBox jCB = new JComboBox();
	JLabel l = new JLabel("选择您要回收的内存块");
	JLabel l1 = new JLabel();
	JLabel l2 = new JLabel();
	JLabel l3 = new JLabel();

	public Recycle() {

		// 界面代码、监听器、提示信息
		this.setIconImage(p.getImage());
		b.setToolTipText("点此随机生成内存状态");
		b.addActionListener(this);
		b2.addActionListener(this);
		b2.setToolTipText("点此回收您所选择的内存块");
		jCB.addItemListener(this);
		jCB.setToolTipText("下拉选择内存块");
		l.setVisible(false);
		l1.setVisible(false);
		jCB.setVisible(false);
		b2.setVisible(false);
		t.setEditable(false);
		p1.setLayout(new GridLayout(9, 1));
		p1.add(l3);
		p1.add(b);
		p1.add(l);
		p1.add(jCB);
		p1.add(l2);
		p1.add(l1);
		p1.add(b2);
		p2.add(sp);
		p2.setLayout(new GridLayout(1, 1));

		// 先产生水平排列方式的Box组件,当作基底容器(BaseBox),将后面的vBox、vBox1添加入这个Box
		Box baseBox = Box.createHorizontalBox();
		add(baseBox);
		// 产生垂直排列方式的Box组件
		Box vBox = Box.createVerticalBox();
		vBox.add(p1);
		p1.setMaximumSize(new Dimension(140, 250));
		baseBox.add(vBox);
		// 产生水平排列方式的Box组件
		Box vBox1 = Box.createHorizontalBox();
		baseBox.add(vBox1);
		vBox1.add(p2);

		setVisible(true);
		setLocation(300, 300);
		setSize(400, 250);
		setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);

	}

	// 统计已分配分区的数量,用于后面指示下拉菜单的长度
	public static int count(mem[] m) {
		int count = 0;

		for (int i = 0; i < m.length; i++) {
			if (m[i].m4 == 1)
				count++;
		}

		return count;
	}

	public static mem[] re(mem[] m, int a) {// 回收算法,m为代表全部内存信息的数组,a是通过下拉菜单选择的内存块序号
		mem[] nm = null;
		if (a == 1) {// 假如是内存表头
			// ////
			if (m[a].m4 == 0) {// 假如第二块是空闲分区,则与第二块合并,起址为该回收块起址,其它各项仅修改序号
				nm = new mem[m.length - 1];
				nm[a - 1] = m[a - 1];
				nm[a - 1].m4 = 0;
				nm[a - 1].m2 += m[1].m2;
				for (int i = 1; i < nm.length; i++) {
					nm[i] = m[i + 1];
					nm[i].m1 -= 1;
				}
			} else {// 假如第二块不是空闲分区,则单独建立一个空闲分区
				m[0].m4 = 0;
				nm = m;
			}
			// ////
		} else {

			if (a == m.length) {// 假如是内存表末
				// //
				if (m[a - 2].m4 == 0) {// 假如倒数第二块是空闲分区,则与倒数第二块合并,起址为该回收块起址,其它各项仅修改序号
					nm = new mem[m.length - 1];
					nm[a - 2] = m[a - 2];
					nm[a - 2].m4 = 0;
					nm[a - 2].m2 += m[a - 1].m2;
					for (int i = 0; i < nm.length - 1; i++) {
						nm[i] = m[i];
					}
				} else {// 假如倒数第二块不是空闲分区,则单独建立一个空闲分区
					m[a - 1].m4 = 0;
					nm = m;
				}
				// //
			} else {// 假如不是第一块也不是最后一块,则有四种情况
				//
				if (m[a - 2].m4 == 0 && m[a].m4 == 0) {// 夹在两块空闲分区中间
					// 建立少两个单位的新数组,存储到该回收区的前两位
					nm = new mem[m.length - 2];
					for (int i = 0; i < a - 2; i++) {
						nm[i] = m[i];
					}
					// 将回收区前一位的大小改为这三个分区的和,然后将后面的元素前移两位,序号也相应减去2
					nm[a - 2] = m[a - 2];
					nm[a - 2].m2 += (m[a - 1].m2 + m[a].m2);
					for (int i = a - 1; i < nm.length; i++) {
						nm[i] = m[i + 2];
						nm[i].m1 -= 2;
					}
				} else {
					if (m[a - 2].m4 == 0) {// 前一块是空闲分区
						// 建立少一个单位的新数组用于存储,将回收区的大小加至前一块空闲分区,后面的元素依次前移一位,序号减一
						nm = new mem[m.length - 1];
						for (int i = 0; i < a - 2; i++) {
							nm[i] = m[i];
						}
						nm[a - 2] = m[a - 2];
						nm[a - 2].m2 += m[a - 1].m2;
						for (int i = a - 1; i < nm.length; i++) {
							nm[i] = m[i + 1];
							nm[i].m1 -= 1;
						}
					} else {
						if (m[a].m4 == 0) {// 后一块是空闲分区
							nm = new mem[m.length - 1];
							// 前面元素不变,将后面的空闲分区大小加至该分区,然后把后面的元素前移一位,序号减一
							for (int i = 0; i < a - 1; i++) {
								nm[i] = m[i];
							}
							nm[a - 1] = m[a - 1];
							nm[a - 1].m4 = 0;
							nm[a - 1].m2 += m[a].m2;
							for (int i = a; i < nm.length; i++) {
								nm[i] = m[i + 1];
								nm[i].m1 -= 1;
							}
						} else {// 前后都是已分配的分区,直接修改分配状态
							m[a - 1].m4 = 0;
							nm = m;
						}
					}
				}
				//
			}

		}

		return nm;// 将代表内存现在状态的nm数组返回

	}

	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		if (e.getSource() == b) {// 假如按下b,则清空JTextPane,显示新生成的内存状态
			t.setText("");
			m = Test.build();
			Test.print(m, t);
			if (count(m) != 0) {// 假如存在需回收内存块,则往下拉菜单添加相应的序号
				jCB.setVisible(true);
				l.setVisible(true);
				l1.setVisible(true);
				b2.setVisible(true);
				jCB.removeAllItems();
				for (int i = 0; i < m.length; i++) {
					if (m[i].m4 == 1)
						jCB.addItem(m[i].m1);
				}
			} else {// 假如统计之后发现无已分配分区,则隐藏与回收相关的项
				jCB.setVisible(false);
				l.setVisible(false);
				l1.setVisible(false);
				b2.setVisible(false);
				add.insert2("\n" + "没有可供回收的内存块", t);
			}
		}

		if (e.getSource() == b2) {

			// 将选中的内存块序号读出
			int select = Integer.parseInt(jCB.getSelectedItem().toString());
			m = re(m, select);
			add.insert2("第" + select + "块内存被回收", t);
			Test.print(m, t);
			jCB.removeAllItems();
			for (int i = 0; i < m.length; i++) {
				if (m[i].m4 == 1)
					jCB.addItem(m[i].m1);
			}
			// 假如已经将所有内存回收,则将与回收有关的项隐藏
			if (jCB.getItemCount() == 0) {
				jCB.setVisible(false);
				l.setVisible(false);
				l1.setVisible(false);
				b2.setVisible(false);
				add.insert2("\n" + "没有可供回收的内存块", t);
			}
		}

	}

	@Override
	public void itemStateChanged(ItemEvent e) {// 下拉项改变则更改l1所显示的内容
		// TODO Auto-generated method stub
		l1.setText("回收第" + jCB.getSelectedItem() + "块内存");
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -