美文网首页
JVM 内存分配和占用

JVM 内存分配和占用

作者: 早点起床晒太阳 | 来源:发表于2020-10-11 10:58 被阅读0次

    我们从一个简单示例来引出JVM的内存模型

    简单示例

    我从一个简单示例谈起这一块,我在看一篇文章的时候看到这么一个场景并且自己做了尝试,就是分配一个2M的数组,使用Xmx即最大内存为12M的话,会报错Java heap space,但是如果Xmx为13M的话这块便能正常执行 代码如下

    public class Main {
        static final int SIZE=2*1024*1024;
        public static void main(String[] a) throws InterruptedException {
            int[] i = new int[SIZE];
            Thread.sleep(30000);
            System.out.println("hahahha");
        }
    }
    

    原因探究

    数组占用大小

    int数组占用的大小为8M 因为一个int占用4个字节,所以210241024*4 相当于8M。
    那么相当于8M在当JVM最大为13M的时候是可以的 12M的时候是放不下的 那么JVM 是具体怎么组成和分配的呢

    查看JVM的具体分配

    我觉得比较直观的是使用

    jmap -heap pid

    这种方式来查看。可以看我上述代码,为了方便查看,我们sleep了30S的时间。
    然后我们执行 java -Xmx13M -jar loaddata-0.0.1-SNAPSHOT.jar时,通过jps 找到其pid 就可以看到相关的占用情况了

    JVM具体的内存分配

    通过上述 jmap -heap pid 的方式 按照Xmx13M 我们查询到了如下所示

    Heap Usage:
    PS Young Generation
    Eden Space:
       capacity = 3670016 (3.5MB)
       used     = 2526440 (2.4094009399414062MB)
       free     = 1143576 (1.0905990600585938MB)
       68.84002685546875% used
    From Space:
       capacity = 524288 (0.5MB)
       used     = 524288 (0.5MB)
       free     = 0 (0.0MB)
       100.0% used
    To Space:
       capacity = 524288 (0.5MB)
       used     = 0 (0.0MB)
       free     = 524288 (0.5MB)
       0.0% used
    PS Old Generation
       capacity = 9961472 (9.5MB)
       used     = 9130440 (8.707466125488281MB)
       free     = 831032 (0.7925338745117188MB)
       91.65753816303454% used
    

    根据这个提发现 JVM的组成其实由2块
    Young Generation 和 Old Generation,他们两个默认比例是1:2.
    而Young Generation又分为Eden Space From Space和 to Space

    这里还涉及到一个大对象内存分配的问题

    JVM的内存首先是往young Generation分配的。但是如果像上述这种大的对象(像上述这种8M数组,而JVM的young Generation是装不下的),就会直接放到old Generation里面.

    由上面观察可知,8M的int数组直接放到了old Generation。

    结论

    根据上面的一些测试得出结论,8M的int数组在放入JVM的时候,由于12M 或者13M的JVM的young Generation均放不下,所以直接放到了old Generation。
    然后13M JVM的old Generation可以放的下8M的int数组,但是12M的JVM的old Generation放不下8M的int数组,所以造成了这个情况。(12M的JVM的old Generation的大小可以自己测试查看,也可以按照2/3进行计算,加上old Generation原有的一些内存占用,可以推断出是不可以的)

    相关文章

      网友评论

          本文标题:JVM 内存分配和占用

          本文链接:https://www.haomeiwen.com/subject/sndrpktx.html