jvm:优化-栈上分配

转载请注明博客来处:https://blog.csdn.net/qq_42709262/article/details/84800251

几乎所有的对象实例,都是在堆上分配的,但存在部分例外,栈上分配就是这种除了堆上分配的例外。

1.栈上分配指的是什么

①将线程中的私有对象打散(即图中user),让它在栈上分配,而不是在堆上分配

比如方法中的user引用,就是方法的局部变量,new的User()实例在堆上,我们需要的就是把这个实例打散:比如我们的实例user中有两个字段,就把这个实例认作它内部的两个字段以局部变量的形式分配在栈上也就是打散,这个操作称为:标量替换

②使用栈上分配策略除了需要开启标量替换还需要开启逃逸分析。什么是逃逸分析?其实就是判断我们将这个user对象会不会return出去,出去了的话,这时候我们对于这个对象来说就不会受用栈上分配,因为后续的代码可能还需要使用这个对象实例,可以说只要是多个线程共享的对象就是逃逸对象

2.栈上分配有什么好处

不需要GC介入去回收这个对象,出栈即释放资源,可以提高性能,原理:由于我们GC每次回收对象的时候,都会触发Stop The World(停止世界),这时候所有线程都停止了,然后我们的GC去进行垃圾回收,如果对象频繁创建在我们的堆中,也就意味这我们也要频繁的暂停所有线程,这对于用户无非是非常影响体验的,栈上分配就是为了减少垃圾回收的次数

3.怎么开启栈上分配

在vm中执行以下命令,堆大小取决于项目,这里仅仅是测试

-server -Xms10m -Xmx10m -XX:+PrintGC -XX:+DoEscapeAnalysis -XX:+UseTLAB -XX:+EliminateAllocations

 -server:指的是让我们的jvm在server模式下运行,简单介绍一下server模式和client模式:分别指的是服务端模式客户端模式,客户端模式优化的是系统启动时间更快,而服务端模式的优化则更关注与系统的整体性能即运行速度,这里由于博主看见很多人都说,栈上分配必须要在server模式下才能运行,秉着实践才是真理.....让代码在client下模式运行,发现与server模式一样的时间,测试代码如下:

client模式:

server模式:

时间是一样的。。。也就是说都开启了栈上分配,但考虑到由于博主的jdk默认是server模式运行,也就是说jvm在运行的时候可能会根据机器的情况自行调整,推测运行模式的命令并非强制性的。当然也仅仅是推测,也无踪可循,由于博主是实战派并非学术派,所以也不会对问题钻研过度。

-Xms10m:定义堆的初始值大小为10m

-Xmx10m:定义堆的最大大小也为10m

-XX:+PrintGC :打印GC日志

-XX:+DoEscapeAnalysis :启用逃逸分析(默认打开)

-XX:+EliminateAllocations :标量替换(默认打开)

-XX:+UseTLAB :开启本地线程分配缓冲(默认打开)就是提前为每个线程分配一块私有内存区域,仅仅是内存分配上的私有,别的线程还是可以对它进行访问、修改之类的操作,只是无法在这上面分配,详解请看另一篇博客虚拟机中的对象

猜你喜欢

转载自blog.csdn.net/qq_42709262/article/details/84800251