要想在栈上分配,那么创建的对象就要很小,而且jvm要开始支持在栈上分配的(默认是开启的)
1. 对象new出来首先放在栈上(前提条件要满足),栈上放不下放在线程本地,线程本地放不下就看对象是不是太大了,如果是很大就放在老年代,如果不是很大就放在eden
---------------------------------------------------------------------------------------------------------------------------------
敲上以下代码
package com.mo;
public class A {
class User {
int id;
String name;
public User(int id, String name) {
this.id = id;
this.name = name;
}
}
User user;
void alloc(int i) {
user = new User(i,"name" + i);
}
public static void main(String[] args) {
A a = new A();
long s1 = System.currentTimeMillis();
for (int i = 0; i < 10000000; i++) {
a.alloc(i);
}
long s2 = System.currentTimeMillis();
System.out.println(s2 - s1);
}
}
1.不使用在栈上分配对象,不适用本地线程缓存
启动程序
2.不使用在栈分配对象,但是使用线程本地缓存
启动程序
3. 使用逃逸分析,使用标量替换(在栈上分配对象,是不用GC来回收的,而是当方法结束的时候该对象就消失.
---------------------------------------------------------------------------------------------------------------------------------
什么是逃逸分析?
是分析对象能不能被分配在栈上
像这种情况是完全可以分配在栈上的
因为这个对象的引用也是在里面,当这个对象没有了,也不会影响到其他对象,可以说是不存在逃逸
但是像这种
是不能分配在栈上的,因为这时候jvm的逃逸分析会进行分析,该对象是否符合逃逸分析,这里是不符合的。该方法结束了,该对象不能没有(当该对象被分配在栈上的时候,方法结束对象就没有了),因为外面还有一个对象指向该对象。如果被分配在栈上了,当方法结束了,该对象就逃逸了
下面是实验验证:
--------------------------------------------------------------------------------------------------------------
看一下其他JVM的参数
线程本地缓存也是使用eden区的,下面验证