java的内存区域管理

java的内存区域:

1、程序计数器:可以认为是当前线程所执行的字节码的字号指示器,同时在多线程情况下,用来记录当前线程执行的位置,从而当线程切换的时候能找到线程之前执行的位置

2、Java虚拟机栈:主要有局部变量表,存放了编译器可知的数据类型,对象引用,可能出现两种异常

StackOverFlowError 如果虚拟机栈的大小不允许动态扩展,当线程请求栈的深度超过当前虚拟机栈的最大深度的时候

OutOfMemoryError 如果允许动态扩展,并且当线程请求栈时内存用完了,抛出此异常

3、本地方法栈,和虚拟机栈功能类似,区别是虚拟机栈为执行java方法(字节码)服务,本地方法栈则为虚拟机用到的native方法服务

4、堆:所有线程共享,用来存放对象实例,是垃圾收集器管理的主要区域,因此也被称为GC堆,可以被细分为新生代老年代

细分一点包括Eden空间,from Survivor To Survivor空间等

5、方法区:用于存储已被虚拟机加载的类信息,常量,静态变量

6、运行时常量池,是方法区的一部分,用于存放编译期生成的各种字面量和符号引用

hotspot虚拟机:对象的创建:

1、类加载检查:

2、分配内存:两种方式 1指针碰撞 2空闲列表

并发问题解决办法:1cas+失败重试 cas是乐观锁的一种实现方式 2 TLAB本地线程分配缓冲

3、初始化零值

4、设置对象头

5、执行init方法

String s1 = new String("abc");这句话创建了几个对象? 两个,常量池的对象,堆内的对象

首先“abc”字符串在编译期放入常量池,然后new的时候new一份字符串“abc”放入堆,然后java栈的str1指向java堆上的“abc”

Integer 缓存

/**
*此方法将始终缓存-128到127(包括端点)范围内的值,并可以缓存此范围之外的其他值。
*/
    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

GC调优策略

GC调优原则:先将机器的jvm参数设置到最优,然后需要根据GC情况分析代码优化:减少创建对象的数量,减少使用全局变量和大对象

GC调优目的:将转移到老年代的对象降低到最小,减少GC的时间

GC调优策略:1、将新生对象留在新生代,因为Full GC成本远高于Minor GC,可以通过 -Xmn调节新生代大小

2、尽量让大对象进入老年代,大对象在新生代可能导致空间不足

3、合理设置进入老年代对象的年龄,减少老年代的内存占用,降低full gc发生的频率

4、设置稳定的堆大小,-Xms初始化堆大小,-Xmx最大堆大小

MinorGC和FullGC

从年轻代空间(包括Eden和Survivor区域)回收内存被称为MinorGC,MajorGC是清理永久代,FullGC是清理整个空间,包括年轻代和永久代

FullGC需要STW,即停止所有活动(stop the world collection),所有的线程都被挂起(除了垃圾收集器)

垃圾回收算法:

1、引用计数,引用计数变为0时,则该对象可回收,不过无法解决两个对象互相引用的问题,因此已不再使用

2、标记清理:从根集(GC Roots)出发寻找所有的引用,找到一个就对其做标记,当追踪完成后,所有未标记的就是需要回收的垃圾,他的标记过程就是可达性分析算法中判断垃圾对象的标记过程

缺点:标记和清除的效率不高,而且标记清除后会产生大量不连续的内存碎片

3、复制算法(copy):将可用内存按容量分为大小相同的两块,每次只用其中一块,当这一块用完了,就将还活着的对象复制到另一块内存上面,然后再把这一块内存空间一次清理掉 

比较适合新生代,因为新生代每次收集都会有大量对象死去,只有少量存活,但是一比一太浪费,因此将内存分为较大的Eden(伊甸园)空间和两块较小的Survivor(幸存者)空间,每次使用Eden和一块Survivor,当回收时,将其中还活着的对象一次性复制到另外一块Survivor上,然后清理掉Eden和Survivor,HotSpot默认比例是Eden:Survivor=8:1,也就是只有10%的空间会浪费

4、标记整理:比较适合老年代,因为老年代存活率比较高,该算法标记和上面标记清理算法一样,但是处理的时候不是直接清理,而是将所有的对象向一端移动,然后直接清理掉端边界以外的内存

5、分代收集:当前商业虚拟机采用的算法,根据对象的存活周期将不同的内存划分成几块,一般是把java堆分为新生代和老年代,他们具体使用的回收算法如下:

GC算法优点缺点存活对象移动内存碎片适用场景
引用计数实现简单不能处理循环引用  
标记清除不需要额外空间两次扫描,耗时严重NY老年代
复制没有标记和清除需要额外空间YN新生代
标记整理没有内存碎片需要移动对象的成本YN老年代

 

常用的垃圾收集器

1、从线程运行情况可以分成三种:1、串行回收,Serial回收器,单线程回收,全程stw。

特点:cpu利用率最高,但是停顿时间比较长

2、并行回收 以Parallel开头的回收器,多线程回收,全程stw

特点:回收时间短,效率高,对吞吐量要求高,一般应用于大型应用,科学计算

3、并发回收,cms与G1,多线程分阶段回收,只有某阶段会stw

cms(Concurrent Mark Sweep)采用了标记清除算法(针对老年代,新生代还是复制算法),不过要复杂一些,分为四个步骤:

初始标记(CMS initial mark)

并发标记(CMS concurrent mark)

重新标记(CMS remark)

并发清除(CMS concurrent sweep)

特点:并发收集,低停顿,响应时间快

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值