都2020年10月24了,你可能还不知道那些JVM的秘密

1、引言

在座的各位程序员们,10月24号,今天还有没有是坐在公司加班的?

小编估计肯定有,谁让我们是程序员,就好比如保卫国家的战士们,总是奋战在战场的前线,来守护老百姓的生活安宁。

不管咋样,小编还是祝贺同胞们节日快乐,永无BUG、永远青春、永不脱发~~~

2、想一想

在小编刚开始学习Java语言的时候,然后知道了JVM,之前老师一直说Java中的实例对象就存储在JVM中的堆区。

先给大家上一张JVM的内存模型图,这图应该很熟悉吧,应该对每一块干什么用的多多少少也有了解个大概。

过了几年,Java中的实例对象全部都是存储在堆区的概念,已经被小编我深深的烙印在心中。

还记得小编在面试的时候,遇到过一个类似的问题:

面试官:你知道Java的实例对象是存储在JVM中哪个区域么? 

小编:堆区。

面试官:那假设在方法中new了一个百万个对象,也还是全部存储在堆区吗?

那么关键的地方来了,当初对于年少无知的小编来说,哪会想那么多,就死脑筋认为只要是实例对象就只会存储在堆区中。

如果小伙伴你们也不知道答案,那么带着这个问题,来看实际操作一波吧。

public class Test_1 {

    public static void main(String[] args) {
       for (int i=0;i < 10000;i++){
           create();
       }
        while (true);

    }

    public static void create(){
        Test_1 test = new Test_1();
    }
}

在代码中,循环了1w次,通过HSDB工具(HSDB可以查看JVM在运行时数据区的内容),很明显能看出,在堆区中,确实存在1w个Test_1对象,那么现在改成把循环改成100w,再看看。

这下好了,count并没有达到100w个,最初小编想的是是不是被GC回收了,然后打印GC日志也没有发现。

那么问题来了,剩下的对象跑哪儿去了???

 

3、看一看

其实这里就涉及到一个知识点,叫做:逃逸分析,默认逃逸分析是开启的,我们先把逃逸分析关闭掉,再试试。

把逃逸分析关闭之后,通过查看对象,这下总算有100w个了。

4、什么是逃逸分析?

用官方的话来说,逃逸分析是一种确定指针动态范围的方法,可以分析在程序的哪些地方可以访问到指针。这里的指针可以理解成java的实例对象的引用地址,而指针动态范围可以理解为对象的访问修饰符(public、private等)。

上面那样的解释估计很多小伙伴都不懂,用代码来举个例子。

在start方法中,new了一个Test_1对象,很明显test_1这个对象是不是只能在start()方法中使用,其他地方都不能够使用。

这种对象就可以理解为不逃逸对象,因为它不能被其他地方访问到。

public class Test_1 {

	public static void main(String[] args) {
		start();
	}

	public static void start() {
	   Test_1 test_1 = new Test_1();
	}
}

那现在将start方法改一下,把test_1这个对象返回出去,那么这个对象就是可以理解为一个逃逸对象,因为它被返回出去了,只要是调用了start这个方法,就可以拿到这个对象,被其他地方访问到。

或者说当一个实例对象的引用指针被多个方法或线程引用时,我们称这个指针发生了逃逸。

	public static Test_1 start() {
		Test_1 test_1 = new Test_1();
		return test_1;
	}

最后通过这种逃逸和不逃逸的现象,来进行分析,就称之为:逃逸分析。

5、栈上分配

栈上分配就是基于逃逸分析这个分析,最后分析出来的一种优化方式,最大的好处应该是减少gc的压力,把那些不逃逸的对象分配在栈上。这样逃逸分析完后可以确定哪些变量可以分配在栈上,栈的分配比堆快,性能好。

这样就像本文一开始演示的一样,100w对象并没有全部在堆中,而把逃逸分析关闭了,就都放在堆中了。

 逃逸分析可以通过这个参数控制,-XX:+/-DoEscapeAnalysis,+就是表示开启,-就是表示关闭。

 下次如果再遇到问对象是不是全部放在堆上堆这种问题,可不要直接说都放在堆上。

当然栈上分配只是其中一种优化,还有包括标量替换锁消除等等,在逃逸分析的时候,如果你定义的对象的方法上有同步锁,但在运行时,却只有一个线程在访问,此时逃逸分析后的机器码,会去掉同步锁运行。

 

看着小编1024还在码文章的份上,点个赞,点个赞,点个赞~~~~~~

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 终极编程指南 设计师:CSDN官方博客 返回首页
实付 29.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值