如何查询应用中垃圾回收器(GC)至今已释放的内存字节数?
查询GC已释放内存字节数的方法
不同编程语言和运行时环境的实现方式不同,以下是几种主流场景的具体操作:
Java
Java标准API没有直接提供GC累计释放的总字节数,需通过监听GC事件并计算内存差值来实现。如果仅需获取单次GC的释放量,可借助GarbageCollectorMXBean获取GC前后的内存使用情况:
import java.lang.management.GarbageCollectorMXBean; import java.lang.management.ManagementFactory; import java.util.List; public class GCFreedBytes { public static void main(String[] args) { List<GarbageCollectorMXBean> gcBeans = ManagementFactory.getGarbageCollectorMXBeans(); // 触发一次GC System.gc(); for (GarbageCollectorMXBean bean : gcBeans) { if (bean.getLastGcInfo() == null) continue; long totalFreed = 0; var beforeGc = bean.getLastGcInfo().getMemoryUsageBeforeGc(); var afterGc = bean.getLastGcInfo().getMemoryUsageAfterGc(); for (String poolName : beforeGc.keySet()) { long usedBefore = beforeGc.get(poolName).getUsed(); long usedAfter = afterGc.get(poolName).getUsed(); totalFreed += (usedBefore - usedAfter); } System.out.printf("%s 本次GC释放字节数: %d%n", bean.getName(), totalFreed); } } }
如果需要累计所有GC释放的字节数,需注册NotificationListener监听GC事件,每次计算内存差值并累加。
Python
Python可通过gc模块结合tracemalloc标准库来统计GC释放的内存:
import gc import tracemalloc # 启动内存跟踪 tracemalloc.start() # 初始GC并记录快照 gc.collect() snapshot_initial = tracemalloc.take_snapshot() # 执行应用逻辑... # 再次GC并记录快照 gc.collect() snapshot_final = tracemalloc.take_snapshot() # 计算两次快照的内存差值(负值为释放的内存) stats = snapshot_final.compare_to(snapshot_initial, 'lineno') total_freed = abs(sum(stat.size_diff for stat in stats if stat.size_diff < 0)) print(f"GC累计释放字节数: {total_freed}")
另外,gc.get_stats()可获取各代GC的回收次数、对象数量等统计,但不直接返回字节数,需结合内存跟踪工具使用。
C#
C#可通过GC类的内存统计方法或PerformanceCounter来计算GC释放的字节数:
方法1:使用GC.GetTotalMemory
using System; class Program { static void Main() { // 获取GC前的内存使用量(不强制垃圾回收) long memoryBefore = GC.GetTotalMemory(false); // 强制触发完整GC并等待终结器执行 GC.Collect(2, GCCollectionMode.Forced, true, true); GC.WaitForPendingFinalizers(); // 获取GC后的内存使用量(强制垃圾回收以获取准确值) long memoryAfter = GC.GetTotalMemory(true); long freedBytes = memoryBefore - memoryAfter; Console.WriteLine($"本次GC释放字节数: {freedBytes}"); } }
方法2:使用PerformanceCounter
using System; using System.Diagnostics; class Program { static void Main() { var processName = Process.GetCurrentProcess().ProcessName; var heapCounter = new PerformanceCounter( ".NET CLR Memory", "# Bytes in all Heaps", processName ); long initialHeap = heapCounter.NextSample().RawValue; GC.Collect(); long finalHeap = heapCounter.NextSample().RawValue; Console.WriteLine($"本次GC释放字节数: {initialHeap - finalHeap}"); } }
累计所有GC释放的字节数需要长期跟踪内存变化,每次GC后计算差值并累加。
内容的提问来源于stack exchange,提问作者Bishal Ghosh
相关产品推荐
相关产品推荐

