为什么我的单线程 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)
我创建了一个简单的 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)