heap和stack有什么区别
2.stack的空间由操作系统自动分配和释放,heap的空间是手动申请和释放的,heap常用new关键字来分配。
3.stack空间有限,heap的空间是很大的自由区。在Java中,若只是声明一个对象,则先在栈内存中为其分配地址空间,若再new一下,实例化它,则在堆内存中为其分配地址。
1功能和作用
堆主要用来存放对象的,堆内存被应用所有的线程共享。
栈 看成方法的运行模型,主要是用来执行程序的。
2性能与存储要求
栈的性能比堆要快,仅次于位于CPU中的寄存器。但是,在分配内存的时候,存放在栈中的数据大小与生存周期必须在编译时是确定的,缺乏灵活性。
堆可以动态分配内存大小,Java的垃圾收集器会自动收走这些不再使用的数据,因此可以得到更大的灵活性。但是,由于要在运行时动态分配内存和销毁对象时都需要占用时间,所以效率低。
3内存的分配与回收
基本类型变量和对象的引用都是在栈内存中分配。
对于引用类型:Java中所有对象的存储空间都是在堆中分配的,但是这个对象的引用却是在栈中分配。也就是说在建立一个对象时,从两个地方都分配内存,在堆中分配的内存实际用于建立这个对象,而在栈中分配的内存只是一个指向这个堆对象的引用而已
被创建时,首先会在栈内存中分配一块空间,然后在堆内存中也会分配一块具体的空间用来存储数据的具体信息,即hash值,然后由栈中引用指向堆中的对象地址.
JVM调优参数有哪些
XX比X的稳定性更差,并且版本更新不会进行通知和说明。
-Xms
s为strating,表示堆内存起始大小
-Xmx
x为max,表示最大的堆内存
(一般来说-Xms和-Xmx的设置为相同大小,因为当heap自动扩容时,会发生内存抖动,影响程序的稳定性)
-Xmn
n为new,表示新生代大小
(-Xss:规定了每个线程虚拟机栈(堆栈)的大小)
-XX:SurvivorRator=8
表示堆内存中新生代、老年代和永久代的比为8: 1: 1
- -XX:MaxTenuringThreshold=15
表示当对象的存活的年龄(minor gc一次加1)大于多少时,进入老年代
Minor GC 和 Full GC Minor GC:回收新⽣代,因为新⽣代对象存活时间很短,因此 Minor GC 会频繁执⾏,执⾏的速度 ⼀般也会⽐较快。 Full GC:回收⽼年代和新⽣代,⽼年代对象其存活时间⻓,因此 Full GC 很少执⾏,执⾏速度会⽐ Minor GC 慢很多
对象的内存分配,就是在堆上分配(也可能经过 JIT 编译后被拆散为标量类型并间接在栈上分 配),对象主要分配在新生代的 Eden 区上,少数情况下可能直接分配在老年代,
分配规则不 固定,取决于当前使用的垃圾收集器组合以及相关的参数配置。
内存分配策略
1 对象优先在 Eden 分配
大部分情况,对象都会首先在 Eden 区域分配,在一次新生代垃圾回收后,如果对象还存活,则会进入 S0 或者 S1,并且对象的年龄还会加 1(Eden 区->Survivor 区后对象的初始年龄变为 1),当它的年龄增加到一定程度(默认为 15 岁),
就会被晋升到老年代中。对象晋升到老年代的年龄阈值,可以通过参数 -XX:MaxTenuringThreshold
来设置。
“Hotspot 遍历所有对象时,按照年龄从小到大对其所占用的大小进行累积,当累积的某个年龄大小超过了 survivor 区的一半时,取这个年龄和 MaxTenuringThreshold 中更小的一个值,作为新的晋升年龄阈值”。
2⼤对象直接进⼊⽼年代
3⻓期存活的对象进⼊⽼年代
.4空间分配担保
MinorGC 前虚拟机必须检查老年代最大可用连续空间是否大于新生代对象总空间,如果满足则说明这次 Minor GC 确定安全。如果不,JVM会查看HandlePromotionFailure 参数是否允许担保失败,如果允许会继续检查老年代最大可用连续空间是否大于历次晋升老年代对象的平均大小,如果满足将Minor GC,否则改成一次 FullGC。
Minor GC vs Major GC/Full GC:
Minor GC:回收新生代(包括 Eden 和 Survivor 区域),因为 Java 对象大多都具备朝生夕 灭的特性,所以 Minor GC 非常频繁,一般回收速度也比较快。
Major GC / Full GC: 回收老年代,出现了 Major GC,经常会伴随至少一次的 Minor GC,但这 并非绝对。Major GC 的速度一般会比 Minor GC 慢 10 倍 以上。
在 JVM 规范中,Major GC 和 Full GC 都没有一个正式的定义,所以有人也简单地认为 Major GC 清理老年代,而 Full GC 清理整个内存堆。