`
boriszhang78
  • 浏览: 21233 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

JVM内存模型测试--Thread

    博客分类:
  • JVM
阅读更多



 今天在SUN的jdk上测试了Thread栈占用内存的情况,帮助进一步了解JVM的内存模型。配置如下:

WIN7+4G 

 

SUN JDK

D:\maven\smart\smart>java -version
java version "1.6.0_21"
Java(TM) SE Runtime Environment (build 1.6.0_21-b06)
Java HotSpot(TM) Client VM (build 17.0-b16, mixed mode, sharing)

 

初始内存情况如下:


    
 

 测试类代码如下:

 

package org.smart.threadtest;

public class ThreadStackTest extends Thread {
	public ThreadStackTest(long num) {
		super("[ThreadStackTest] Thread:" + num);
	};

	public void run() {
		String threadName = Thread.currentThread().getName();
		// System.out.println(threadName + " start.");
		try {
			Thread.sleep(10000);
		} catch (Exception e) {
			System.out.println("Exception from " + threadName + ".run");
		}
	}

	public static void main(String[] args) {
		ThreadStackTest t2 = null;
		for (int i = 0; i < 10000; i++) {
			System.out.println("Thread " + i + " start...");
			t2 = new ThreadStackTest(i);
			t2.start();
		}

	}
}

 

 

 测试配置为:每个线程分配10240k就是10M的Stack,heap分配1024M,命令行如下:

D:\Java\jdk1.6.0_20\bin\java -Djava.compiler=NONE -verbose:gc -XX:+HeapDumpOnOutOfMemoryError 
	-XX:HeapDumpPath=d:/temp/java.phd   -Xms1024m -Xmx1024m -XX:+PrintGCDetails 
	-XX:+PrintHeapAtGC -XX:ThreadStackSize=10240  -cp D:\maven\smart\smart\target\test-classes\ 
	org.smart.threadtest.ThreadStackTest

 

 输出结果:

  

Thread 72 start...
Thread 73 start...
Thread 74 start...
Thread 75 start...
Thread 76 start...
Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread
        at java.lang.Thread.start0(Native Method)
        at java.lang.Thread.start(Thread.java:597)
        at org.smart.threadtest.ThreadStackTest.main(ThreadStackTest.java:22)
Heap
 def new generation   total 314560K, used 14417K [0x03b50000, 0x190a0000, 0x190a0000)
  eden space 279616K,   5% used [0x03b50000, 0x0493ba48, 0x14c60000)
  from space 34944K,   0% used [0x16e80000, 0x16ea8d18, 0x190a0000)
  to   space 34944K,   0% used [0x14c60000, 0x14c60000, 0x16e80000)
 tenured generation   total 699072K, used 0K [0x190a0000, 0x43b50000, 0x43b50000)
   the space 699072K,   0% used [0x190a0000, 0x190a0000, 0x190a0200, 0x43b50000)
 compacting perm gen  total 12288K, used 2088K [0x43b50000, 0x44750000, 0x47b50000)
   the space 12288K,  16% used [0x43b50000, 0x43d5a110, 0x43d5a200, 0x44750000)
No shared spaces configured.

 

从输出可以看出,启动了76个线程之后,内存溢出,有两个比较奇怪的地方:

1、没有产生heapdump文件(注:如果是heap内存满可以产生,测试过,配置没有错)

2、在WIN7资源监视器中显示内存基本没有波动,也就是说这些内存只是被jvm标记,没有实际使用,包括heap--我猜

 

76×10M + 1024M = 1784M 大概为 1800M左右,和操作系统空闲差200M

 

修改测试配置,将heap大小调整到124M,命令如下:

 

D:\Java\jdk1.6.0_20\bin\java -Djava.compiler=NONE -verbose:gc -XX:+HeapDumpOnOutOfMemoryError 
	-XX:HeapDumpPath=d:/temp/java.phd   -Xms124m -Xmx124m -XX:+PrintGCDetails 
	-XX:+PrintHeapAtGC -XX:ThreadStackSize=10240  -cp D:\maven\smart\smart\target\test-classes\ 
	org.smart.threadtest.ThreadStackTest

 输出结果:

Thread 161 start...
Thread 162 start...
Thread 163 start...
Thread 164 start...
Thread 165 start...
Thread 166 start...
Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread
        at java.lang.Thread.start0(Native Method)
        at java.lang.Thread.start(Thread.java:597)
        at org.smart.threadtest.ThreadStackTest.main(ThreadStackTest.java:23)
Heap
 def new generation   total 38080K, used 23783K [0x2bee0000, 0x2e830000, 0x2e830000)
  eden space 33856K,  69% used [0x2bee0000, 0x2d5ef4b8, 0x2dff0000)
  from space 4224K,   4% used [0x2e410000, 0x2e43a860, 0x2e830000)
  to   space 4224K,   0% used [0x2dff0000, 0x2dff0000, 0x2e410000)
 tenured generation   total 84672K, used 0K [0x2e830000, 0x33ae0000, 0x33ae0000)
   the space 84672K,   0% used [0x2e830000, 0x2e830000, 0x2e830200, 0x33ae0000)
 compacting perm gen  total 12288K, used 369K [0x33ae0000, 0x346e0000, 0x37ae0000)
   the space 12288K,   3% used [0x33ae0000, 0x33b3c710, 0x33b3c800, 0x346e0000)
    ro space 10240K,  54% used [0x37ae0000, 0x3805b760, 0x3805b800, 0x384e0000)
    rw space 12288K,  55% used [0x384e0000, 0x38b7f798, 0x38b7f800, 0x390e0000)

 

结果显示启动了166个线程。

166×10M + 124M  = 1784M 大概为1800M,结果和上面的对比一下,可以知道TreadStack确实占用的是操作系统内存,和heapsize本身无关。

 

 

IBM JDK:

java version "1.6.0"
Java(TM) SE Runtime Environment (build pwi3260sr8fp1ifix-20100924_01(SR8 FP1+IZ81201+IZ80998+IZ83034+IZ83273))
IBM J9 VM (build 2.4, JRE 1.6.0 IBM J9 2.4 Windows 7 x86-32 jvmwi3260sr8ifx-20100923_65174 (JIT enabled, AOT enabled)
J9VM - 20100923_065174
JIT  - r9_20100401_15339ifx6
GC   - 20100308_AA)
JCL  - 20100728_01

 

测试类还是沿用上面测试SUN JDK的类:ThreadStackTest

设置环境变量:

IBM_HEAPDUMP_OUTOFMEMORY=TRUE

IBM_HEAPDUMPDIR=<directory>

IBM_JAVACOREDIR=<directory>

IBM_JAVADUMP_OUTOFMEMORY=TRUE

 

测试配置也相同:每个线程分配10240k就是10M的Stack,heap分配1024M,命令行如下:

 

D:\Java\ibm_jdk16.0\bin\java -Djava.compiler=NONE -verbose:gc,sizes -Xms1024m -Xmx1024m -Xss10240K -Xiss10240K  
-cp D:\maven\smart\smart\target\test-classes\ org.smart.threadtest.ThreadStackTest

 

输出如下:

<?xml version="1.0" ?>

<verbosegc version="20100308_AA">

  -Xmca32K        RAM 类分段增量
  -Xmco128K       ROM 类分段增量
  -Xmns0K         初始新空间大小
  -Xmnx0K         最大新空间大小
  -Xms1G          初始内存大小
  -Xmos1G         初始旧空间大小
  -Xmox1G         最大旧空间大小
  -Xmx1G          最大内存
  -Xmr16K         已记住的集合大小
  -Xmso256K       操作系统线程堆栈大小
  -Xiss10M        Java 线程堆栈初始大小
  -Xssi16K        Java 线程堆栈增量
  -Xss10M         Java 线程堆栈最大大小
<initialized>
  <attribute name="gcPolicy" value="-Xgcpolicy:optthruput" />
  <attribute name="maxHeapSize" value="0x40000000" />
  <attribute name="initialHeapSize" value="0x40000000" />
  <attribute name="compressedRefs" value="false" />
  <attribute name="pageSize" value="0x1000" />
  <attribute name="requestedPageSize" value="0x1000" />
</initialized>

Thread 0 start...
Thread 1 start...
Thread 2 start...
......
......
Thread 81 start...
Thread 82 start...
<sys id="1" timestamp="Jan 26 14:35:08 2011" intervalms="0.000">
  <time exclusiveaccessms="0.050" meanexclusiveaccessms="0.050" threads="0" lastthreadtid="0x41F92300" />
  <refs soft="6" weak="4" phantom="0" dynamicSoftReferenceThreshold="32" maxSoftReferenceThreshold="32" />
  <tenured freebytes="1072352000" totalbytes="1073741824" percent="99" >
    <soa freebytes="1018665216" totalbytes="1020055040" percent="99" />
    <loa freebytes="53686784" totalbytes="53686784" percent="100" />
  </tenured>
  <gc type="global" id="1" totalid="1" intervalms="0.000">
    <classunloading classloaders="0" classes="0" timevmquiescems="0.000" timetakenms="0.087" />
    <finalization objectsqueued="2" />
    <timesms mark="13.684" sweep="4.105" compact="0.000" total="17.950" />
    <tenured freebytes="1072855776" totalbytes="1073741824" percent="99" >
      <soa freebytes="1019168992" totalbytes="1020055040" percent="99" />
      <loa freebytes="53686784" totalbytes="53686784" percent="100" />
    </tenured>
  </gc>
  <tenured freebytes="1072855776" totalbytes="1073741824" percent="99" >
    <soa freebytes="1019168992" totalbytes="1020055040" percent="99" />
    <loa freebytes="53686784" totalbytes="53686784" percent="100" />
  </tenured>
  <refs soft="1" weak="4" phantom="0" dynamicSoftReferenceThreshold="31" maxSoftReferenceThreshold="32" />
  <time totalms="18.043" />
</sys>

JVMDUMP006I 正在处理转储事件“systhrow”,详细信息“java/lang/OutOfMemoryError”- 请稍候。
JVMDUMP032I JVM 使用“D:\IBM SOFT\IBM JVM\jca401\Snap.20110126.143508.15788.0001.trc”来请求 Snap 转储以响应事件
JVMDUMP010I Snap 转储已写入 D:\IBM SOFT\IBM JVM\jca401\Snap.20110126.143508.15788.0001.trc
JVMDUMP032I JVM 使用“d:\temp\heapdump.20110126.143508.15788.0002.phd”来请求 Heap 转储以响应事件
JVMDUMP010I Heap 转储已写入 d:\temp\heapdump.20110126.143508.15788.0002.phd
JVMDUMP032I JVM 使用“d:\temp\javacore.20110126.143508.15788.0003.txt”来请求 Java 转储以响应事件
JVMDUMP010I Java 转储已写入 d:\temp\javacore.20110126.143508.15788.0003.txt
JVMDUMP013I 已处理转储事件“systhrow”,详细信息:“java/lang/OutOfMemoryError”。
Exception in thread "main" java.lang.OutOfMemoryError: 未能分配 JNIEnv
        at java.lang.Thread.startImpl(Native Method)
        at java.lang.Thread.start(Thread.java:887)
        at org.smart.threadtest.ThreadStackTest.main(ThreadStackTest.java:23)

 

 

82×10M + 1024M = 1844M,IBM JDK能够产生heapdump和core文件,这点比SUN JDK强,core文件内容如下:

 

 

 

同样将heapsize调整为124M测试,命令如下:

 

D:\Java\ibm_jdk16.0\bin\java -Djava.compiler=NONE -verbose:gc,sizes -Xms124m -Xmx124m -Xss10240K -Xiss10240K  
-cp D:\maven\smart\smart\target\test-classes\ org.smart.threadtest.ThreadStackTest

 

输出如下:

<?xml version="1.0" ?>

<verbosegc version="20100308_AA">

  -Xmca32K        RAM 类分段增量
  -Xmco128K       ROM 类分段增量
  -Xmns0K         初始新空间大小
  -Xmnx0K         最大新空间大小
  -Xms124M        初始内存大小
  -Xmos124M       初始旧空间大小
  -Xmox124M       最大旧空间大小
  -Xmx124M        最大内存
  -Xmr16K         已记住的集合大小
  -Xmso256K       操作系统线程堆栈大小
  -Xiss10M        Java 线程堆栈初始大小
  -Xssi16K        Java 线程堆栈增量
  -Xss10M         Java 线程堆栈最大大小
<initialized>
  <attribute name="gcPolicy" value="-Xgcpolicy:optthruput" />
  <attribute name="maxHeapSize" value="0x7c00000" />
  <attribute name="initialHeapSize" value="0x7c00000" />
  <attribute name="compressedRefs" value="false" />
  <attribute name="pageSize" value="0x1000" />
  <attribute name="requestedPageSize" value="0x1000" />
</initialized>

Thread 0 start...
Thread 1 start...
......
......
Thread 169 start...
Thread 170 start...
<sys id="1" timestamp="Jan 26 14:42:31 2011" intervalms="0.000">
  <time exclusiveaccessms="0.079" meanexclusiveaccessms="0.079" threads="0" lastthreadtid="0x0030EC00" />
  <refs soft="6" weak="4" phantom="0" dynamicSoftReferenceThreshold="32" maxSoftReferenceThreshold="32" />
  <tenured freebytes="128516864" totalbytes="130023424" percent="98" >
    <soa freebytes="122016000" totalbytes="123522560" percent="98" />
    <loa freebytes="6500864" totalbytes="6500864" percent="100" />
  </tenured>
  <gc type="global" id="1" totalid="1" intervalms="0.000">
    <classunloading classloaders="0" classes="0" timevmquiescems="0.000" timetakenms="0.061" />
    <finalization objectsqueued="2" />
    <timesms mark="2.994" sweep="0.623" compact="0.000" total="3.768" />
    <tenured freebytes="129057424" totalbytes="130023424" percent="99" >
      <soa freebytes="122556560" totalbytes="123522560" percent="99" />
      <loa freebytes="6500864" totalbytes="6500864" percent="100" />
    </tenured>
  </gc>
  <tenured freebytes="129057424" totalbytes="130023424" percent="99" >
    <soa freebytes="122556560" totalbytes="123522560" percent="99" />
    <loa freebytes="6500864" totalbytes="6500864" percent="100" />
  </tenured>
  <refs soft="1" weak="4" phantom="0" dynamicSoftReferenceThreshold="31" maxSoftReferenceThreshold="32" />
  <time totalms="3.899" />
</sys>

JVMDUMP006I 正在处理转储事件“systhrow”,详细信息“java/lang/OutOfMemoryError”- 请稍候。
JVMDUMP032I JVM 使用“D:\IBM SOFT\IBM JVM\jca401\Snap.20110126.144231.10464.0001.trc”来请求 Snap 转储以响应事件
JVMDUMP010I Snap 转储已写入 D:\IBM SOFT\IBM JVM\jca401\Snap.20110126.144231.10464.0001.trc
JVMDUMP032I JVM 使用“d:\temp\heapdump.20110126.144231.10464.0002.phd”来请求 Heap 转储以响应事件
JVMDUMP010I Heap 转储已写入 d:\temp\heapdump.20110126.144231.10464.0002.phd
JVMDUMP032I JVM 使用“d:\temp\javacore.20110126.144231.10464.0003.txt”来请求 Java 转储以响应事件
JVMDUMP010I Java 转储已写入 d:\temp\javacore.20110126.144231.10464.0003.txt
JVMDUMP013I 已处理转储事件“systhrow”,详细信息:“java/lang/OutOfMemoryError”。
Exception in thread "main" java.lang.OutOfMemoryError: 未能分配 JNIEnv
        at java.lang.Thread.startImpl(Native Method)
        at java.lang.Thread.start(Thread.java:887)
        at org.smart.threadtest.ThreadStackTest.main(ThreadStackTest.java:23)
</verbosegc>

 

 

170×10M + 124M = 1824M  ,与上面内存数量基本一致。

 

IBM JDK表现与SUN的JDK基本一致,都是占用栈的内存,即进程寻址空间>操作系统可用内存?操作系统可用内存-heapsize:进程寻址空间-heapsize

  

 

分享到:
评论

相关推荐

    MSB企业级JVM优化与性能调优课程 解读JVM内部机制-针对性解决企业架构优化问题

    JVM(Java虚拟机)内存模型主要包括堆内存(Heap)、方法区(Method Area)、程序计数器(Program Counter Register)、虚拟机栈(Virtual Machine Stack)和本地方法栈(Native Method Stack)。其中: - **堆内存...

    JVM内存溢出

    【JVM内存溢出】指的是Java...总的来说,解决JVM内存溢出问题需要深入了解Java内存模型,合理配置JVM参数,并结合性能监控工具进行诊断和优化。这不仅可以避免服务器因内存问题崩溃,还能提升整体系统的稳定性和性能。

    Java内部测试题1-3(包含题目和详细参考答案等)

    这些测试题涵盖了初级到中高级的Java语言概念,包括但不限于基础语法、面向对象编程、集合框架、异常处理、多线程、IO流、网络编程以及JVM内存模型等多个方面。 1. **基础语法**:这部分可能涉及变量定义、数据类型...

    jvm.rar_test 2410

    6. **内存模型**:Java内存模型(JMM)定义了线程如何共享和访问内存,确保多线程环境下的正确性。它涵盖了主内存和工作内存的概念,以及volatile、synchronized等关键字的作用。 7. **异常处理**:Java使用try-...

    jvm支持最大线程数简单测试

    jvm支持的最大线程数是受多种因素影响的,包括java堆内存大小、Thread的Stack内存大小、系统最大可创建的线程数量等。通过调整这些参数,可以影响jvm支持的最大线程数。 2. 影响jvm支持最大线程数的因素 影响jvm...

    java面试题测试代码.zip

    - 深入理解JVM内存模型(堆、栈、方法区、本地方法栈和程序计数器)。 8. **设计模式**: - 单例模式、工厂模式、观察者模式、装饰器模式等常见的设计模式及其应用场景。 9. **最新技术趋势**: - Spring Boot...

    C++ JAVA 软件测试面试题汇总

    - **JVM(Java Virtual Machine)**:Java程序的运行平台,理解垃圾回收机制、类加载器和JVM内存模型对优化Java程序很重要。 - **多线程**:Java提供了丰富的并发工具,如Thread类、Runnable接口、synchronized...

    Java后端体系高级面试题

    这些题目旨在测试候选人的专业知识、问题解决能力以及在实际项目中的应用技能。以下是一些可能涵盖的关键知识点: 1. **Java基础知识**: - 面向对象特性:封装、继承、多态 - 内存管理:垃圾回收机制,对象的...

    面试题集--C++ JAVA 测试面试必看

    5. **JVM**:内存模型(堆、栈、方法区等),垃圾回收机制。 6. **设计模式**:单例、工厂、观察者、装饰者等23种经典设计模式。 7. **Java 8及以上新特性**:Lambda表达式、Stream API、Optional类等。 最后,我们...

    java题库测试

    - 线程创建:Thread类和Runnable接口。 - 线程同步:synchronized关键字,wait()、notify()和notifyAll()方法。 - 线程池:ExecutorService、ThreadPoolExecutor和Future接口。 - 线程安全的数据结构:...

    java程序员面试题

    - **JVM内存模型**:堆、栈、方法区等区域的划分。 - **调优**:JVM参数设置,如-Xms, -Xmx, -XX:MaxHeapFreeRatio等。 8. **IO流**: - **字节流与字符流**:了解它们的区别,以及BufferedReader和...

    125条常见的java面试笔试题大汇总

    9. **JVM内存模型** - 堆、栈、方法区、本地方法栈、程序计数器的作用。 - 内存溢出和内存泄漏问题。 - 类加载机制:加载、验证、准备、解析、初始化。 10. **设计模式** - 常见的设计模式:单例、工厂、观察者...

    java面试题_高频题

    - **JVM内存模型**:Java虚拟机有堆、栈、方法区、本地方法栈和程序计数器五大部分。 - **垃圾收集**:Java自动进行内存管理,垃圾收集器负责回收不再使用的对象所占用的内存。 - **内存泄漏**:虽然Java有垃圾...

    JAVA面试题 帮需要帮助的

    - 虚拟机内存模型:堆、栈、方法区的结构和作用。 10. **设计模式**: - 常见设计模式:单例、工厂、观察者、装饰器、适配器等。 - 设计原则:开闭原则、里氏替换原则、依赖倒置原则等。 以上只是部分Java面试...

    java一下测试题目和答案

    - **内存模型**:理解堆、栈、方法区、本地方法栈和程序计数器的作用。 - **垃圾回收**:学习GC的工作原理和垃圾收集器,优化内存管理。 以上是Java初学者需要掌握的基础知识点,这份测试题集覆盖了这些内容,...

    Java 笔试面试下载

    - 性能优化:分析JVM内存模型,进行性能调优。 10. **框架与工具**: - Spring框架:理解依赖注入(DI)和面向切面编程(AOP)的概念。 - Maven或Gradle:掌握构建工具的使用,管理项目依赖。 - JUnit或TestNG...

Global site tag (gtag.js) - Google Analytics