Java 堆的描述是:所有的对象实例以及数组都应该运行时分配在堆上
数组和对象可能永远不会存储在栈上,因为栈帧中保存引用,这个引用指向对象或者数组在堆中的位置
在方法结束以后,堆中的对象不会被马上移除,而是等下一次垃圾回收的时候才会移除
Java 8 中把堆内存分为:新生区,养老区,元空间
堆空间分代思想为什么要把 Java 堆分代,不分代就不能正常工作了吗
其实不分代完全可以, 唯一理由是优化 GC 性能
优先分配到 Eden 区
大对象(比较长的字符串,数组)直接分配到老年代(避免程序中出现过多的大对象)
长期存活的对象分配到老年代
对象分配堆区是线程共享的区域,任何线程都可以访问到堆中的共享区域。
由于对象实例的创建在 JVM 中非常频繁,因此在并发的环境下,从堆中划分内存空间是线程不安全的。
为避免多个线程操作同一个地址,需要加锁,但会影响分配速度
逃逸分析:代码优化1、栈上分配,将堆分配转换为栈分配。
2、同步省略,如果一个对象被发现只能从一个线程被访问到,对于这个对象的操作可以不考虑同步
3、分离对象或者标量替换,有的对象可能不需要作为一个连续的内存结构存在也可以被访问到,那么对象部分可以不存储在内存,而是 CPU 的寄存器中



