📄 recycle.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 + -