为什么我的单线程 java 程序消耗的资源超过最大堆大小?

why my single threaded java program is consuming more than max heap size?

我创建了一个简单的 java 程序 :-

import java.util.ArrayList;
import java.util.List;
import java.lang.management.ManagementFactory;

public class OOMError {

    public static List<Person> list = new ArrayList<>();

    public static void main(String args[]){

    System.out.println("Process Id: "+ManagementFactory.getRuntimeMXBean().getName());
        try{
            while(true){
                List<Person> innerList = new ArrayList<>();

                for(int i=0;i<1000000;i++) {
                    list.add(new Person());
                }

                int count = 0;

                while(count < 60){
                    for(int i=0;i<100000;i++){
                        innerList.add(new Person());
                    }
                    Thread.sleep(1000*60);
                    count=count+5;
                }

                Thread.sleep(1000*60*10);

            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    public static class Person{
        private String fName ;
        private String lName;

        Person(){
            fName = new String("Stack");
            lName = new String("Overflow");
        }
    }
}

我运行这个程序用导出JAVA_OPTS='-Xms128m -Xmx1024m'

我正在通过 top 命令监控我的 java 应用程序 RAM 使用情况。

Processes: 94 total, 10 running, 2 stuck, 82 sleeping, 2765 threads                                                                                           06:59:51
Load Avg: 2.62, 2.74, 2.68  CPU usage: 0.11% user, 0.54% sys, 99.33% idle  SharedLibs: 13M resident, 25M data, 0B linkedit.
MemRegions: 28079 total, 19G resident, 24M private, 3449M shared. PhysMem: 2776M wired, 19G active, 3718M inactive, 25G used, 39G free.
VM: 605G vsize, 1199M framework vsize, 118994555(0) pageins, 0(0) pageouts. Networks: packets: 80924129/10G in, 112346940/77G out.
Disks: 4011149/367G read, 9149138/634G written.

PID    COMMAND      %CPU   TIME     #TH   #WQ  #POR #MRE RPRVT  RSHR RSIZE  VPRVT  VSIZ PGRP  PPID  STATE   UID  FAULTS  COW  MSGS MSGR SYSBSD  SYSMACH CSW     PAGE
89038  java         0.0    02:01.65 31    2    112  437  1237M  10M  1251M  2101M  19G  89038 88799 stuck   501  321189  448  651  300  250145+ 358994  304415+ 0

我很惊讶,当我的最大堆大小为 1024M 并且状态为 "stuck" 时,我的 RSIZE 字段怎么会是 1251M?

堆满后会发生什么?应用程序会终止吗?

我正在使用 OS X 10.X.X

在 JRockit 博客中有一篇文章对此进行了解释:

The command line argument -Xmx sets the maximum Java heap size (mx). All java objects are created on the Java heap, but the total memory consumption of the JVM process consist of more things than just the Java heap. A few examples:

  • Generated (JIT:ed) code
  • Loaded libraries (including jar and class files)
  • Control structures for the java heap
  • Thread Stacks
  • User native memory (malloc:ed in JNI)

来源:Why is my JVM process larger than max heap size?