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

unhi4e5o  于 2021-06-30  发布在  Java
关注(0)|答案(1)|浏览(386)

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

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. import java.lang.management.ManagementFactory;
  4. public class OOMError {
  5. public static List<Person> list = new ArrayList<>();
  6. public static void main(String args[]){
  7. System.out.println("Process Id: "+ManagementFactory.getRuntimeMXBean().getName());
  8. try{
  9. while(true){
  10. List<Person> innerList = new ArrayList<>();
  11. for(int i=0;i<1000000;i++) {
  12. list.add(new Person());
  13. }
  14. int count = 0;
  15. while(count < 60){
  16. for(int i=0;i<100000;i++){
  17. innerList.add(new Person());
  18. }
  19. Thread.sleep(1000*60);
  20. count=count+5;
  21. }
  22. Thread.sleep(1000*60*10);
  23. }
  24. } catch (InterruptedException e) {
  25. e.printStackTrace();
  26. }
  27. }
  28. public static class Person{
  29. private String fName ;
  30. private String lName;
  31. Person(){
  32. fName = new String("Stack");
  33. lName = new String("Overflow");
  34. }
  35. }
  36. }

我用export java_opts='-xms128m-xmx1024m'运行了这个程序
我通过top命令监视java应用程序ram的使用情况。

  1. Processes: 94 total, 10 running, 2 stuck, 82 sleeping, 2765 threads 06:59:51
  2. 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.
  3. MemRegions: 28079 total, 19G resident, 24M private, 3449M shared. PhysMem: 2776M wired, 19G active, 3718M inactive, 25G used, 39G free.
  4. VM: 605G vsize, 1199M framework vsize, 118994555(0) pageins, 0(0) pageouts. Networks: packets: 80924129/10G in, 112346940/77G out.
  5. Disks: 4011149/367G read, 9149138/634G written.
  6. 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
  7. 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并且状态是“卡住”时,我的rsize字段是1251m?
一旦我的堆满了会发生什么?申请会终止吗?
我正在使用os x 10.x.x

wbgh16ku

wbgh16ku1#

jrockit博客中有一篇文章对此进行了解释:
命令行参数 -Xmx 设置最大java堆大小(mx)。所有java对象都是在java堆上创建的,但是jvm进程的总内存消耗不仅仅是java堆。举几个例子:
生成(jit:ed)代码
加载的库(包括jar和类文件)
java堆的控制结构
线程堆栈
用户本机内存(malloc:ed in jni公司)
来源:为什么我的jvm进程大于最大堆大小?

相关问题