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)
|
||
|
||
# 更 |