- JVM内存划分,如下图
GC 主要工作在 Heap 区和 MetaSpace 区(上图蓝色部分),在 Direct Memory 中,
如果使用的是 DirectByteBuffer,那么在分配 内存不够时则是 GC 通过 Cleaner#clean 间接管理,
任何自动内存管理系统都会面临的步骤:为新对象分配空间,然后收集垃圾对象空间。
- 对象的分配流程
重点说下栈上分配和TLAB分配:
栈上分配是指什么?
将线程中的私有对象打散(即图中city),让它在栈上分配,而不是在堆上分配。
比如方法中的city引用,就是方法的局部变量,new的City()实例在堆上,
我们需要的就是把这个实例打散:比如我们的实例city中有两个字段,
就把这个实例认作它内部的两个字段以局部变量的形式分配在栈上也就是打散,这个操作称为:标量替换
使用栈上分配策略除了需要开启标量替换,还需要开启逃逸分析。什么是逃逸分析?
其实就是判断我们将这个city对象会不会return出去,出去了的话,这时候我们对于这个对象来说
就不会受用栈上分配,因为后续的代码可能还需要使用这个对象实例,
可以说只要是多个线程共享的对象就是逃逸对象,JVM会分析不会逃逸的对象且能够进行标量替换,优先分配在
栈上
栈上分配的好处?
不需要GC介入去回收这个对象,出栈即释放资源,可以提高性能,
原理:由于我们GC每次回收对象的时候,都会触发Stop The World(停止世界),
这时候所有线程都停止了,然后我们的GC去进行垃圾回收,如果对象频繁创建在我们的堆中,
也就意味这我们也要频繁的暂停所有线程,这对于用户无非是非常影响体验的,
栈上分配就是为了减少垃圾回收的次数
对应参数有三个,默认都是开启的:
-XX:+DoEscapeAnalysis :启用逃逸分析
-XX:+EliminateAllocations :标量替换
-XX:+UseTLAB :开启本地线程分配缓冲