package com.company.java.oop.instance;
2.如何检测对象分配在哪里了?JVM 参数配置
-XX:+PrintGC 输出GC基本信息,
1)-Xmx5m -Xms5m -XX:-DoEscapeAnalysis -XX:+PrintGC(输出GC日志)
- 2)-Xmx5m -Xms5m -XX:+DoEscapeAnalysis -XX:+PrintGC
3.JDK8中逃逸分析默认开启了吗?开启了
-XX:+DoEscapeAnalysis -XX:-DoEscapeAnalysis 关闭
5.JVM参数测试:(在堆内存有限的情况下测试JVM逃逸分析)
1)最大堆 -Xmx5m -Xms5m -XX:+DoEscapeAnalysis -XX:+PrintGC(输出GC日志)
2)最小堆 -Xmx5m -Xms5m -XX:-DoEscapeAnalysis -XX:+PrintGC
总结:
1.对象创建时有可能分配在堆(逃逸对象)上也有可能分配在栈(未逃逸对象)上. - 2.方法内部创建的小对象并且没有逃逸可能分配在栈上.
- 3.默认打开逃逸分析对JVM的执行会有性能上的提高(
- 因为栈上分配的对象,不需要启动GC进行回收),GC回收时,程序会停止
- 4.设计对象时,假如对象不会被多线程共享,多个方法共享,
- 那么,此时对象的引用应尽量使用局部变量.
public class TestObjectInstance01 {
public static void main(String[] args) {
long start=System.currentTimeMillis();
for(int i=0;i<1000000;i++) {
alloc01();
}
long end=System.currentTimeMillis();
System.out.println(end-start);
}
//JDK6以后的HotSpot虚拟机已经支持运行时
//对对象进行逃逸分析.
//如何理解对象逃逸?
未逃逸对象
/* 1)**未逃逸对象**:方法内创建的对象没有被外界引用.下面的array01是未逃逸对象
* 现阶段的JDK中未逃逸的小对象可能会分配在栈上
*/
static void alloc01() {
//创建一个只能存储一个字节的对象数组
byte[] array01=new byte[1];
//在下标为0的位置存储整数10
array01[0]=10;
}
逃逸对象
/* 2)逃逸对象:方法内创建的对象被外界引用.下面的array02是逃逸对象
* 现阶段的JDK中逃逸的小对象可能会分配在堆上
*/
static byte[] array02;
static void alloc02() {
//创建一个只能存储一个字节的对象数组
array02=new byte[1];
//在下标为0的位置存储整数10
array02[0]=10;
}
}