fix: add memory pressure guard to prevent OOM during heavy OCR load#5819
fix: add memory pressure guard to prevent OOM during heavy OCR load#5819
Conversation
Greptile SummaryThis PR adds a memory-pressure circuit breaker to Changes:
Issues found:
Confidence Score: 3/5
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[captureTimer fires] --> B{isMonitoring?}
B -- No --> Z[return]
B -- Yes --> C{isInSpecialSystemMode?}
C -- Yes --> Z
C -- No --> D{isMemoryPressureHigh?\nresident_size > 1.5 GB}
D -- Yes --> E[memoryPressureDropCount++]
E --> F{count == 1 OR\ncount % 30 == 0?}
F -- Yes --> G[log: Skipping capture\nN frames dropped]
F -- No --> Z
G --> Z
D -- No --> H{memoryPressureDropCount > 0?}
H -- Yes --> I[log: Recovered after N frames\nmemoryPressureDropCount = 0]
H -- No --> J[continue capture pipeline]
I --> J
J --> K{isVideoCallApp?}
K -- Yes, throttled --> Z
K -- No / allowed frame --> L[captureFrame & OCR]
|
| } | ||
| } | ||
| guard result == KERN_SUCCESS else { return false } | ||
| return info.resident_size > memoryPressureThresholdBytes |
There was a problem hiding this comment.
resident_size overstates actual app memory footprint
resident_size (RSS) includes all physical pages currently mapped into the process address space — including shared system frameworks (AppKit, CoreFoundation, etc.) that are shared across every macOS app. This means the 1.5 GB guard will trip earlier than necessary, potentially suspending capture even when the app's true memory usage is well within limits.
Apple's recommended metric for actual process memory pressure is phys_footprint from task_vm_info_data_t, which only counts memory pages actually charged to this process. Consider using it for a more accurate threshold:
private func isMemoryPressureHigh() -> Bool {
var info = task_vm_info_data_t()
var count = mach_msg_type_number_t(MemoryLayout<task_vm_info_data_t>.size) / 4
let result = withUnsafeMutablePointer(to: &info) {
$0.withMemoryRebound(to: integer_t.self, capacity: Int(count)) {
task_info(mach_task_self_, task_flavor_t(TASK_VM_INFO), $0, &count)
}
}
guard result == KERN_SUCCESS else { return false }
return info.phys_footprint > memoryPressureThresholdBytes
}160bde0 to
0cbaf63
Compare
c3231b0 to
411ec88
Compare
|
Hey @kodjima33 👋 Friendly reminder — this PR has been quiet for a bit. If you don't need further assistance from the CTO, feel free to go ahead and merge it. Let's close the loop and not let it go stale. Thanks! |
Fixes #5791
Problem: During video calls, OCR processing can't keep up with capture rate, causing memory to spike to 2-3GB and potentially OOM crash.
Fix: Added a memory pressure safety valve that skips frame capture entirely when the app's resident memory exceeds 1.5GB. This complements the existing per-frame backpressure mechanism with a global memory-based circuit breaker.
mach_task_basic_info.resident_sizebefore each captureScope: Minimal bug fix — no new features or refactoring.