You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中类与普通变量的内存使用差异及优化问询

Hey there! Let's unpack what's going on with your memory usage tests and how to address your concerns as a Java developer transitioning to Python.

First, a critical clarification about your memory measurement

Your test uses resource.getrusage().ru_maxrss, which returns the maximum resident memory size your process has used since it started—not the current memory usage at the time of the call. That's why your later tests all show the same 80195584 value: it's the peak memory hit during the earlier int_replace_test, and subsequent tests never exceeded that peak. This means your initial conclusion about "old memory not being released" might be off-base.

To get accurate current memory usage for each test, use a tool like psutil instead:

import psutil
import os

def get_current_rss():
    return psutil.Process(os.getpid()).memory_info().rss

Replace your resource calls with this function, and you'll see the actual memory changes during each test.

Why the class-based tests showed higher peak memory

When you work with a class instance:

  • The instance holds a reference to the sample integer object for the duration of the test. For large integers (like the sum of 1 to 1e6), this object takes up more memory, and it stays in memory until the instance is garbage-collected.
  • Method calls also create small temporary stack frames, but these are usually cleaned up quickly by Python's garbage collector.

In contrast, when you use a simple variable:

  • After the loop ends, the large integer is no longer referenced (once you print it, unless you keep the variable around), so the GC can reclaim that memory immediately. But since ru_maxrss tracks peaks, you wouldn't see this drop in your original output.

Fixes for memory efficiency in your class-based code

Since you need to use classes to manage multiple variables, here are actionable optimizations:

  • Use __slots__ to reduce instance memory overhead
    Python instances have a default __dict__ to store attributes, which uses extra memory. By defining __slots__, you disable this dict and specify exactly which attributes your class will have, cutting down memory usage significantly (especially if you create many instances):
class Sample:
    __slots__ = ['sample']  # Explicitly declare attributes
    def __init__(self):
        self.sample = 0
    def increase(self, amt):
        self.sample += amt
    def replace(self, amt):
        self.sample = amt
  • Verify there are no unintended references
    Make sure your actual code isn't holding onto old objects in other attributes (e.g., lists, dictionaries that accumulate values). If you have collections that grow indefinitely, those will cause real memory bloat—clean them up when they're no longer needed.

  • Test with tracemalloc to pinpoint leaks
    If you suspect a real memory leak, use Python's built-in tracemalloc to track exactly where memory is being allocated:

import tracemalloc

tracemalloc.start()
int_test()  # Run your function
snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics('lineno')

print("\nTop memory allocations:")
for stat in top_stats[:5]:
    print(stat)

This will show you which lines are creating the most memory-heavy objects.

Final note for Java devs

Python's garbage collection is automatic, but it works differently from Java's. You rarely need to manually trigger it, but understanding reference counts and avoiding unnecessary object retention is key. For most cases, the class-based approach won't cause memory leaks—your initial test results were skewed by the peak memory measurement.

内容的提问来源于stack exchange,提问作者william

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:59:14