gpt4 book ai didi

java - 运行时 - 为什么 freeMemory() 没有显示正确消耗的内存?

转载 作者:搜寻专家 更新时间:2023-11-01 02:54:57 24 4
gpt4 key购买 nike

下面是检查内存的代码片段

public class TestFreeMemory {

public static void main(String ... args){

Runtime rt = Runtime.getRuntime();
System.out.println("Free Memory (Before GC): " + rt.freeMemory());

rt.gc();
System.out.println("Free Memory (After GC1): " + rt.freeMemory());

rt.gc(); // Second time to ensure results are consistent
// MAY BE has collected all non-reachable objects
System.out.println("Free Memory (After GC2): " + rt.freeMemory());

String s = new String("abcd");
Integer i = new Integer(12345);
System.out.println("Free Memory (After String Creation): " + rt.freeMemory());
// Why is freeMemory not reflecting the memory consumed by two objects
}

}

输出是

Free Memory (Before GC): 1859672
Free Memory (After GC1): 1911768
Free Memory (After GC2): 1911768
Free Memory (After String Creation): 1911768

为什么 freeMemory 没有反射(reflect)两个对象消耗的内存?


更清楚地说,问题是关于 getMemory() 调用没有显示预期结果,即使创建了两个对象并且与 GC 无关。进行两次 GC 调用只是为了尝试确保 getMemory() 调用的次数正确..顺便说一句,创建对象后没有 GC 调用..所以请注意,我不是在创建对象后尝试 GC ..

最佳答案

HotSpot JVM 上的内存管理:

Another desirable garbage collector characteristic is the limitation of fragmentation. When the memory for garbage objects is freed, the free space may appear in small chunks in various areas such that there might not be enough space in any one contiguous area to be used for allocation of a large object. One approach to eliminating fragmentation is called compaction, discussed among the various garbage collector design choices below.

Memory Management in HotSpot JVM (PDF Format).

此行为可能非常依赖于垃圾回收的特定实现。例如:

Parallel Mark Compact

  • Stop-the-world
  • Heap divided into fixed-size chunks (> 2kb now, will likely increase or be subject to ergonomics)
  • Chunk is unit of live data summarization
  • Parallel mark
  • Record live data addresses in external bitmap
  • Find per chunk live data size
  • Find dense chunks, i.e., ones that are (almost) full of live objects

我制作了这个示例(滥用字符串连接以占用更多内存):

public class TestFreeMemory {

static void allocateSomeMemory(){
long[][] array = new long[400][400];
}

public static void main(String ... args){

Runtime rt = Runtime.getRuntime();

allocateSomeMemory(); // once we leave, our array is not reachable anymore
System.out.println("Free Memory (Before GC): " + rt.freeMemory());
rt.gc();
System.out.println("Free Memory (After GC): " + rt.freeMemory());

String a = new String("A");
for(int i = 0; i < 100; i++){
a+="B";
}

System.out.println("Free Memory (After String Creation): " + rt.freeMemory());
// Less free memory expected.
}

}

输出:

Free Memory (Before GC): 3751800

Free Memory (After GC): 5036104

Free Memory (After String Creation): 5012048


如果我在循环中使用相对较少的迭代次数(例如 10 次),额外的空间不会出现在 freeMemory() 中,我会得到如下内容:

Free Memory (Before GC): 3751800

Free Memory (After GC): 5036040

Free Memory (After String Creation): 5036040

关于java - 运行时 - 为什么 freeMemory() 没有显示正确消耗的内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3421869/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com