138 lines
4.3 KiB
Python
138 lines
4.3 KiB
Python
|
|
from dataclasses import dataclass, field
|
|||
|
|
from typing import List, Dict, Optional, Tuple
|
|||
|
|
import math
|
|||
|
|
|
|||
|
|
|
|||
|
|
class MemoryAllocationStrategy:
|
|||
|
|
"""
|
|||
|
|
内存分配策略
|
|||
|
|
"""
|
|||
|
|
FIRST_FIT = 'first_fit' # 首次适应算法
|
|||
|
|
BEST_FIT = 'best_fit' # 最佳适应算法
|
|||
|
|
WORST_FIT = 'worst_fit' # 最坏适应算法
|
|||
|
|
|
|||
|
|
|
|||
|
|
@dataclass
|
|||
|
|
class MemoryBlock:
|
|||
|
|
"""
|
|||
|
|
表示内存块
|
|||
|
|
"""
|
|||
|
|
start_address: int # 起始地址
|
|||
|
|
size: int # 内存块大小
|
|||
|
|
is_free: bool = True # 是否空闲
|
|||
|
|
process_id: Optional[int] = None # 占用该内存块的进程ID
|
|||
|
|
|
|||
|
|
|
|||
|
|
class MemoryManager:
|
|||
|
|
"""
|
|||
|
|
管理内存分配、释放和虚拟内存
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
def __init__(
|
|||
|
|
self,
|
|||
|
|
total_memory: int = 1024 * 1024, # 默认1MB
|
|||
|
|
page_size: int = 4096, # 4KB页大小
|
|||
|
|
allocation_strategy: str = MemoryAllocationStrategy.FIRST_FIT
|
|||
|
|
):
|
|||
|
|
self.total_memory = total_memory # 总内存大小
|
|||
|
|
self.page_size = page_size # 页大小
|
|||
|
|
self.allocation_strategy = allocation_strategy # 分配策略
|
|||
|
|
|
|||
|
|
# 内存块映射
|
|||
|
|
self.memory_map: List[MemoryBlock] = [
|
|||
|
|
MemoryBlock(0, total_memory)
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
# 虚拟内存的页表
|
|||
|
|
self.page_table: Dict[int, List[Tuple[int, bool]]] = {}
|
|||
|
|
|
|||
|
|
# 缺页跟踪
|
|||
|
|
self.total_memory_accesses = 0
|
|||
|
|
self.page_faults = 0
|
|||
|
|
|
|||
|
|
def allocate_memory(
|
|||
|
|
self,
|
|||
|
|
process_id: int,
|
|||
|
|
memory_size: int
|
|||
|
|
) -> Optional[int]:
|
|||
|
|
"""
|
|||
|
|
为进程分配内存
|
|||
|
|
|
|||
|
|
:param process_id: 请求内存的进程ID
|
|||
|
|
:param memory_size: 要分配的内存大小
|
|||
|
|
:return: 分配的内存起始地址,分配失败返回None
|
|||
|
|
"""
|
|||
|
|
# 根据分配策略选择内存分配方法
|
|||
|
|
allocation_method = {
|
|||
|
|
MemoryAllocationStrategy.FIRST_FIT: self._first_fit_allocation,
|
|||
|
|
MemoryAllocationStrategy.BEST_FIT: self._best_fit_allocation,
|
|||
|
|
MemoryAllocationStrategy.WORST_FIT: self._worst_fit_allocation
|
|||
|
|
}.get(self.allocation_strategy)
|
|||
|
|
|
|||
|
|
return allocation_method(process_id, memory_size)
|
|||
|
|
|
|||
|
|
def _first_fit_allocation(
|
|||
|
|
self,
|
|||
|
|
process_id: int,
|
|||
|
|
memory_size: int
|
|||
|
|
) -> Optional[int]:
|
|||
|
|
"""
|
|||
|
|
首次适应内存分配策略
|
|||
|
|
|
|||
|
|
:param process_id: 请求内存的进程ID
|
|||
|
|
:param memory_size: 要分配的内存大小
|
|||
|
|
:return: 分配的内存起始地址,分配失败返回None
|
|||
|
|
"""
|
|||
|
|
for i, block in enumerate(self.memory_map):
|
|||
|
|
if block.is_free and block.size >= memory_size:
|
|||
|
|
# 如果内存块大于请求大小,则分割块
|
|||
|
|
if block.size > memory_size:
|
|||
|
|
new_block = MemoryBlock(
|
|||
|
|
block.start_address + memory_size,
|
|||
|
|
block.size - memory_size
|
|||
|
|
)
|
|||
|
|
self.memory_map.insert(i + 1, new_block)
|
|||
|
|
|
|||
|
|
# 更新原内存块
|
|||
|
|
block.is_free = False
|
|||
|
|
block.process_id = process_id
|
|||
|
|
block.size = memory_size
|
|||
|
|
|
|||
|
|
return block.start_address
|
|||
|
|
|
|||
|
|
return None
|
|||
|
|
|
|||
|
|
def _best_fit_allocation(
|
|||
|
|
self,
|
|||
|
|
process_id: int,
|
|||
|
|
memory_size: int
|
|||
|
|
) -> Optional[int]:
|
|||
|
|
"""
|
|||
|
|
最佳适应内存分配策略
|
|||
|
|
|
|||
|
|
:param process_id: 请求内存的进程ID
|
|||
|
|
:param memory_size: 要分配的内存大小
|
|||
|
|
:return: 分配的内存起始地址,分配失败返回None
|
|||
|
|
"""
|
|||
|
|
best_block = None
|
|||
|
|
best_block_index = -1
|
|||
|
|
smallest_difference = float('inf')
|
|||
|
|
|
|||
|
|
for i, block in enumerate(self.memory_map):
|
|||
|
|
if block.is_free and block.size >= memory_size:
|
|||
|
|
difference = block.size - memory_size
|
|||
|
|
if difference < smallest_difference:
|
|||
|
|
smallest_difference = difference
|
|||
|
|
best_block = block
|
|||
|
|
best_block_index = i
|
|||
|
|
|
|||
|
|
if best_block:
|
|||
|
|
# 如果内存块大于请求大小,则分割块
|
|||
|
|
if best_block.size > memory_size:
|
|||
|
|
new_block = MemoryBlock(
|
|||
|
|
best_block.start_address + memory_size,
|
|||
|
|
best_block.size - memory_size
|
|||
|
|
)
|
|||
|
|
self.memory_map.insert(best_block_index + 1, new_block)
|
|||
|
|
|
|||
|
|
# 更
|