JAVA 内存

Java把内存划分成两种:一种是栈内存,一种是堆内存。

 

 

1功能和作用

与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆

堆主要用来存放对象的,堆内存被应用所有的线程共享。Java堆可以处于物理上不连续的内存空间,它逻辑上是连续的即可.


 

栈 看成方法的运行模型,主要是用来执行程序的。栈的内存地址是连续的

 


 

2性能与存储要求

 

stack空间有限 .栈的性能比堆要快,仅次于位于CPU中的寄存器。但是,在分配内存的时候,存放在栈中的数据大小与生存周期必须在编译时是确定的,缺乏灵活性。

 

heap的空间是很大的自由区。 堆可以动态分配内存大小,Java的垃圾收集器会自动收走这些不再使用的数据,因此可以得到更大的灵活性。但是,由于要在运行时动态分配内存和销毁对象时都需要占用时间,所以效率低。

 3内存的分配与回收

基本类型变量和对象的引用都是在栈内存中分配。

所有的对象实例和数组都在heap分配  

对于引用类型:Java中所有对象的存储空间都是在堆中分配的,但是这个对象的引用却是在栈中分配。也就是说在建立一个对象时,从两个地方都分配内存,在堆中分配的内存实际用于建立这个对象,而在栈中分配的内存只是一个指向这个堆对象的引用而已

在Java中,若只是声明一个对象,则先在栈内存中为其分配地址空间,若再new一下,实例化它,则在堆内存中为其分配地址。


Integer 在堆
int 在栈

内存分配策略

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。

 

 

posted on 2022-01-09 12:34  cltt  阅读(57)  评论(0编辑  收藏  举报

导航