JVM--堆 7.4

1.堆

  • 一个JVM实例只存在一个堆空间,堆也是管理java内存的核心区域
  • java堆区在jvm启动时就被创建,空间大小就确定,堆是jvm管理的最大一块内存空间,堆得大小是可以设置的
  • 堆可以处于物理上不连续的内存空间,但在逻辑上它应该视为连续
  • 所有的线程共享堆,在这里还可以划分分线程私有的缓冲区(Thread Local Allocation Buffer )TLAB
  • 所有的对象实例以及数组都应该在运行时分配在堆上
  • 数组和对象可能永远不会存储在栈中,因为栈帧中保存引用,这个引用指向对象和数组在堆中的位置
  • 方法结束后,堆中的对象不会马上被移除,仅仅在垃圾回收时才会被移除
  • 堆是垃圾回收器(Garbge Collection)重点回收的对象

2.堆内存逻辑分为
新生代(Young Generation space)+养老区(Old Generation space)+元空间(Meta space)

  • 设置堆空间大小 -Xms 表示堆区的起始内存(年轻代+老年代) 等价于 -XX:InitialHeapSize
    -Xmx表示堆区的最大内存 等价于 -XX:MaxHeapSize
    3.OOM(OutOfMemory)

4.年轻代和老年代

  • 存储在jvm的java对象可以划分为两类:一类生命周期特别短,创建和消亡都非常迅速,另一类生命周期很长,极端情况可能与JVM生命周期一直
  • java堆区细分为老年代和年轻代 :
    1)年轻代又可分为Eden空间、Survivor0 (from区)和Survivor1空间(to区)
    2)新生代一般占用1/3的堆空间,其中eden占新生代的8/10,s1区占1/10,s0占1/10,老年代占用2/3堆空间
    3)几乎所有的java对象都在eden区就new出来,绝大部分的java对象的销毁在eden区
    4)对象分配过程:
    a)new的对象先放入eden区,eden有大小限制
    b)当eden区装满时,此时需要new对象时,Minor GC会对eden进行垃圾回收,将eden不再使用的对象销毁,并将幸存对象放入空的s0区并计数age为1
    c)当eden再次装满时,Minor GC再次垃圾回收,将幸存的对象放入s1区,如果此时s0区的对象再次存活,则方入s1区,计数+1,
    d)长此以往,当计数达到15时,就会被放入老年区,计数参数是可以设置的

5.Minor GC、Major GC 和 Full GC

  • GC回收,并非每次都是针对三大内存区域(新生代、老年代、方法区)回收
  • GC按照回收区域分为部分收集(Partial GC)和整堆收集(Full GC)
  • 部分收集:不是完整收集java堆得垃圾收集
    a)Minor GC :只是新生代的收集,触发机制:eden区满,s0和s1区满不会触发Minor GC,因为java对象具,备朝生夕灭的特性,所以Minor GC会比较频繁,但处理速度快,当Minor GC回收,会触发STW,暂停用户线程
    b)major GC:真是针对老年代收集
    c)FullGC:收集整个java堆和方法区的垃圾回收 :触发条件,调用system.gc()
    、老年代空间不足、方法区空间不足、通过Minor GC进入老年代平均大小大于老年代的可用内存、在eden区中s0区和s1区复制时对象大于To Space可用
    内存则将对象转入老年区,且老年区的可用内存小于该对象大小

6.内存分配策略
针对不同年龄段的对象分配原则

  • 优先分配值eden区
  • 大对象直接分配到老年代(尽量避免程序出现过多的大对象)
  • 长期存活的对象分配至老年代
  • 动态年龄分配:如果survivor区中相同年龄的所有对象的大小总和大于survivor空间的一般,年龄大于或者等于该年龄对象可以直接进入老年代,无需等到阈值
  • 空间分配担保

7.TLAB

  • 为什么要有TLAB?
    堆区是线程共享区域,任何线程都可以访问到堆区的共享数据,在并发环境下划分内存空间是线程不安全的,为避免多个线程操作同一地址,需要枷锁,但枷锁会影响分配速度
  • 什么是TLAB
    从内存模式中,在eden区继续进行划分,为每个线程分配一个私有的缓冲区域,它包含在Eden区,使用TLAB可以避免一系列线程不安全问题,还能提高内存的吞吐,因此我们可以将这种内存分配模式称为快速分配策略
    8.逃逸分析
  • new对象实体是否有可能在方法外部调用
package com.pingan;

public class EscapeAnalysis {
	public EscapeAnalysis obj;
	
	/*
	 * 方法返回EscapeAnalysis对象,发生逃逸
	 */
	public EscapeAnalysis getInstance()
	{
		return obj == null ? new EscapeAnalysis():obj;
	}
	
	/*
	 * 为成员变量赋值,发生逃逸
	 */
	public void setObj()
	{
		this.obj = new EscapeAnalysis();
	}
	
	/*
	 * 对象的作用域仅在当期方法有效,没有发生逃逸
	 */
	public void userEscapeAnalysis() {
		EscapeAnalysis s = new EscapeAnalysis();
	}
	
	/*
	 * 引用成员函数,发生逃逸
	 */
	public void userEscapeAnalysis1() {
		EscapeAnalysis s = getInstance();
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值