jvm内存相关详解

一.内存区域分配

jvm内存简单分为程序计数器,栈,堆,以及方法区

便于理解,这里通过创建实例变量对象以及调用来讲一下各个区域的分工.

先列举下程序中一个类需要加载的数据:

类的基本信息(包括代码),常量(final修饰,不可改变),局部变量,静态变量,native方法(调用底层方法的非java方法),以及方法信息

1.场景:代码中new一个新对象a.

先加载这个类,类的信息,常量,静态变量保存在方法区中,为该类分配内存,内存分配在中,包含对象头以及实例数据,对象头中包含该对象的属性,如类元数据的指针(区分对象所属类),对象年龄代,哈希吗,持有锁线程等等,

这里可以看出,方法区和堆一定是所有线程共享的,因为所有的线程都有可能需要访问一个类的信息或者一个对象的信息.

2.场景:某个线程开始执行代码,程序计数器记录代码的执行位置,代码进入了一个方法,方法中申请了局部变量int i=1,然后调用到了刚刚new的对象a

这时这个线程拥有一个单独的程序计数器;进入了这个方法后,虚拟机栈中定义了一块地方为这个方法的栈,栈中目前保存了方法的信息以及局部变量表:int i(代码:int i=1),reference a(代码中调用的对象);其中栈中reference保存的数据就是堆内存中a变量的对象地址,调用该对象的时候,虚拟机很容易的通过指针找到对应的堆内存中的数据

这里可以看出,程序计数器和虚拟机栈一定是线程私有的,每个线程只能用自己的计数器和栈,以免混乱.

二.垃圾回收(CG)

讨论到jvm垃圾回收,这里讨论三个问题:什么样的内存可以回收?什么时候回收?怎样回收?

1.什么样的内存可以回收?

我们用的java虚拟机的判断是否可以回收的方法是可达性分析算法,即对象和cg根节点没有引用链即可以回收,这里引用分为四种:强引用,软引用,弱引用,虚引用,回收时强引用始终不会被回收,软引用只有在即将内存溢出的时候回收,弱引用和虚引用会被回收.

2.什么时候回收:

GC又分为 minor GC 和 Full GC (也称为 Major GC )。Java 堆内存分为新生代和老年代,新生代中又分为1个 Eden 区域 和两个 Survivor 区域。大多数情况下,直接在 Eden 区中进行分配。如果 Eden区域没有足够的空间,那么就会发起一次 Minor GC,长期存活的对象会进入老年代,这里标志是:经历一次cg没有被回收,则年龄加一,到一定年龄(默认15),就会被放入老年代,如果老年代没有足够空间的话,那么就会进行一次 Full GC,即stop the word,这个cg停顿时间较长.

还有一个空间分配担保的问题,在发生Minor GC之前,虚拟机会先检查老年代最大可用的连续空间是否大于新生代所有对象的总空间。如果大于则进行Minor GC,如果小于则看HandlePromotionFailure设置是否允许担保失败(不允许则直接Full GC)。如果允许,那么会继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小,如果大于则尝试Minor GC(如果尝试失败也会触发Full GC),如果小于则进行Full GC。

3.如何回收?

上边提到过,判断是否需要回收是通过可达性算法,算法里的cg根节点在java程序中是全局的引用(常量或静态变量)与栈中的本地变量表,在程序中,进行方法调用,跳转的时候会生成安全点,程序只有在运行到安全点的时候可以进行cg,在安全点上,jvm会生成一次oopmap.来显示当前内存的引用关系,堆内存中那些数据是有cg根节点链接的,收集器根据oopmap情况进行收集.

举例说明:jvm需要进行一次minor cg,这时产生一个标志位说明需要cg,各个线程在执行到安全点上的时候轮询检查该标志位,发现jvm让各个线程停顿进行cg,从而线程发生停顿,内存页设置成不可读,垃圾收集器进行垃圾收集;其中在sleep状态或者挂起状态的线程是处在安全区域中,垃圾收集时不会管安全区域中线程.

具体的新生代如何回收内存的问题,则需要读者查阅资料,因为java垃圾收集器有很多,有的适合老年代,有的适合新生代,还有是否可以共用的问题,不同的收集器收集内存的方法是不一样的,但是目的都是减少停顿时间,以及内存空间合理整理(最重要的是cms收集器,用的是标记-清除方法,即先标记需要清除的部分,在回收标记的部分).

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值