jvm垃圾回收策略之标记清除

垃圾回收指的是对 jvm堆内存的回收。

一. java虚拟机栈

二、本地方法栈(Native Method Stack)

  本地方法栈的功能和特点类似于虚拟机栈,均具有线程隔离的特点以及都能抛出StackOverflowError和OutOfMemoryError异常。

  不同的是,本地方法栈服务的对象是JVM执行的native方法,而虚拟机栈服务的是JVM执行的java方法。如何去服务native方法?native方法使用什么语言实现?怎么组织像栈帧这种为了服务方法的数据结构?虚拟机规范并未给出强制规定,因此不同的虚拟机实可以进行自由实现,我们常用的HotSpot虚拟机选择合并了虚拟机栈和本地方法栈。

局部变量表 (是一组变量值存储空间,用于存放方法参数方法内定义的局部变量。)

操作数栈(其实就是个临时数据存储区域,通过入栈出栈 来进行计算的) 工作原理图

堆内存模型图如下: 包括 年轻代、 老年代(年轻代又分为 伊甸区 , 存活区0  存活区1)   可以看出 如果堆内存总共是3GB, 新生代 : 老年代内存默认占比为 1GB:2GB, 而伊甸区 和 2个存活区的默认占比是8 :1 :1

讲一件jvm的垃圾回收策略, 标记清除。

新生代, 垃圾回收,  是monitor gc, 简称小gc,什么时候触发monitor-gc呢?

   一般创建的对象都会存入 年轻代 , 有的会存入老年代(后面会讲)

   jvm有mark算法,知道那些是标记存货对象, 这些存活对象不会被清理,伊甸区90%都是垃圾,清理伊甸区之前会将伊甸区的存活对象复制到存活区s0,然后sweep扫掉伊甸区的所有对象(所以比较快。一扫而尽)。

当伊甸区满了以后,就开始重复上面的动作, 回收年轻代的垃圾。

  什么时候触发full-gc?

jvm垃圾回收策略之标记清除图解:
      

《深入理解Java虚拟机》

GC详解及Minor GC和Full GC触发条件总结
https://blog.csdn.net/wyl_1483061559/article/details/82726128

JVM调优目标:使用较小的内存占用来获得较高的吞吐量或者较低的延迟

Java虚拟机--垃圾收集器--CMS收集器
CMS(Concurrent Mark Sweep)remark意思是标记的有意思, 收集器是一种以获取最短回收停顿时间为目标的收集器。目前很大一部分的Java应用集中在互联网网站或者基于浏览器的B/S系统的服务端上,这类应用通常都会较为关注服务的响应速度,希望系统停顿时间尽可能短,以给用户带来良好的交互体验。CMS收集器就非常符合这类应用的需求。从名字(包含“Mark Sweep”)上就可以看出CMS收集器是基于标记-清除算法实现的

java中堆和栈有什么区别?  https://blog.csdn.net/weixin_38719347/article/details/80889505
java中堆和栈属于不同的内存区域,使用目的也不同.
java虚拟机栈(注意区别于本地方法栈 Native Method Stack)常用于存储栈帧(栈帧包含:1.局部变量区 2.操作数栈 3.帧数据区 ), 而对象总是在堆上分配.
栈通常都比较小,也不会在多个线程之间共享,而堆被整个JVM的所有线程共享.

JVM内存模型: 运行时数据区包含如下:
方法区(包含运行时常量池)  堆  所有线程共享的
虚拟机栈 本地方法栈  程序计数器(这个不会发生内存溢出,其它几个都会)  线程不共享, 即都是是线程隔离的,即每个线程都有自己独立的虚拟机栈。

https://blog.csdn.net/mine_song/article/details/71517200

每当线程调用一个Java方法时,JVM就会在该线程对应的栈中压入一个帧,
这个帧自然就成了当前帧。当执行这个方法时,它使用这个帧来存储参数、局部变量、中间运算结果等等。
Java栈的组成元素——栈帧, 栈帧由三部分组成:

在Java虚拟机规范中,Java栈(Java Stack)也可以被称之为Java虚拟机栈(Java Virtual Machine Stack),
Java栈主要用于存储栈帧(Stack Frame),也就是说栈帧是Java虚拟机栈的组成元素
而栈帧中则负责存储局部变量表、操作数栈、动态链接和方法返回值等信息。

1.局部变量区、
2.操作数栈(操作数栈其实就是个临时数据存储区域,它是通过入栈和出栈来进行操作的,如100+98  为100入栈 98入栈,计算出198出栈,赋值给局部变量区的第三个)、
3.动态链接和方法返回值等
   
虚拟机栈 和 本地方法栈 的区别?  https://blog.csdn.net/weixin_42414212/article/details/114072750   
一、虚拟机栈(VM Stack)
1.1)什么是虚拟机栈
  虚拟机栈是用于描述java方法执行的内存模型。
  
  每个java方法在执行时,会创建一个“栈帧(stack frame)”,
    栈帧的结构分为“局部变量表、操作数栈、动态链接、方法出口”几个部分
    (具体的作用会在字节码执行引擎章节中讲到,这里只需要了解栈帧是一个方法执行时所需要数据的结构)。
    我们常说的“堆内存、栈内存”中的“栈内存”指的便是虚拟机栈,确切地说,指的是虚拟机栈的栈帧中的局部变量表,因为这里存放了一个方法的所有局部变量。
  方法调用时,创建栈帧,并压入虚拟机栈;方法执行完毕,栈帧出栈并被销毁  
二、本地方法栈 Native Method Stack 
       功能和特点类似于虚拟机栈,均具有线程隔离的特点以及都能抛出StackOverflowError和OutOfMemoryError异常
       本地方法栈服务的对象是JVM执行的native方法,而虚拟机栈服务的是JVM执行的java方法


i=1在内存怎么分配,基本数据类型, 进入栈保存.


jvm参数主要有哪几种分类?
1.以- 开头的是    标准参数   java -version; java -help; java -jar
2.以-X 开头的是   非标准参数  在将来的jvm版本中可能会发生变化  如-Xms:初始堆大小   
3.以-XX 开头的是  不稳定参数  主要用于jvm调优和debug  如-XX:NewRatio:设置新生代和老年代的比 此类参数设置合理可以大大
                              提高JVM的性能及稳定性
                              
young Generation                           
tenured generation(老年代简称tenured gen) 

  Full GC相对于Minor GC来说,停止用户线程的STW(stop the world)时间过长,至少慢10倍以上,所以要尽量避免
  
讲一讲对象的分配规则:  同时也就讲了Monitor GC(Eden区分配不够时进行一次Monitor GC) 和 Full GC的触发条件(1.调用System.gc  2.老年代空间不足 )
1.对象优先分配在Eden区,如果Eden区没有足够的空间,虚拟机进行一次Monitor GC
2.大对象直接进入老年代(大对象是指需要大量内存空间的对象).这样做的目的是避免在Eden区和两个Survivor区之间发生大量的内存copy(新生代通过复制算法收集内存)
3.长期存活的对象进入老年代(即从Eden区和Survivor区通过mark标记选中复制多次到Survivor区,年龄大的),虚拟机为每个对象定一个年龄计数器,如果对象经过了1次Monitor GC 那么对象会进入Survivor区,之后每经过一次Monitor GC那么对象的年年龄加1,直到达到阈值(默认是15),对象进入老年代
4.动态判断对象的年龄.如果Survivor区中相同年龄的所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象可以直接进入老年代.

5.空间分配担保    -XX:HandlePromotionFailure:true/false   是否设置空间分配担保  JDK7及以后这个参数就失效了。
       只要老年代的连续空间大于新生代对象的总大小或者历次晋升到老年代的对象的平均大小就进行MinorGC,否则FullGC。
       
HotSpot中空间分配检查的代码片段
bool TenuredGeneration::promotion_attempt_is_safe(size_t
max_promotion_in_bytes) const {
   // 老年代最大可用的连续空间
   size_t available = max_contiguous_available();  
   // 每次晋升到老年代的平均大小
   size_t av_promo  = (size_t)gc_stats()->avg_promoted()->padded_average();
   // 老年代可用空间是否大于平均晋升大小,或者老年代可用空间是否大于当此GC时新生代所有对象容量
   bool   res = (available >= av_promo) || (available >=
max_promotion_in_bytes);
  return res;
}

不稳定参数分为3类: 
1.性能参数:用于JVM的性能调优和内存分配控制,如内存大小的设置
2.行为参数:用于改变JVM的基础行为,如GC的方式和算法的选择  如-XX:+UseG1GC
3.调试参数: 用于监控.打印,输出jvm的信息.

https://www.cnblogs.com/leeego-123/p/11572786.html

java -server 
-Xms4G 
-Xmx4G 
-Xmn2G 
-XX:NewRatio=2
-XX:SurvivorRatio=1
-XX:PretenureSizeThreshold=<字节大小>  
  默认值是0,意味着任何对象都会先在新生代分配内存,
  该参数可以设分配到新生代对象的大小限制 
  任何比这个大的对象都不会尝试在新生代分配,将直接在老年代分配内存。
  典型的大对象就是很长的字符串或者数组,它们在被创建后会直接进入老年代,
  这样做的目的是避免在Eden区和两个Survivor区之间发生大量的内存复制(新生代采用复制算法)
-XX:PermSize=20M      设置方法区的初始大小
-XX:MaxPermSize=30M   设置方法区的最大值
-XX:+UseConcMarkSweepGC  意思是使用CMS垃圾回收器   (Concurrent Mark Sweep)回收器是在最短回收停顿时间为前提的回收器,属于多线程回收器,采用标记-清除算法。
-XX:MetaspaceSize=128M  
      https://blog.csdn.net/u011069294/article/details/107393331
      JVM方法区(元空间)大小设置(-XX:MetaspaceSize和-XX:MaxMetaspaceSize)
      方法区跟Java堆一样,也是线程共享的区域,它用于存储虚拟机加载的类、常量、静态变量、即时编译器编译后的代码等数据,常量池即在方法区存在
      在JDK1.8开始有了元空间区(Matespace)来替换永久代(Permanent Generation),
      Metaspace使用的是本地内存,而不是堆内存,也就是说在默认情况下Metaspace的大小只与本地内存大小有关
      超过这个值就会引发Full GC,这个值不是固定的,是会随着JVM的运行进行动态调整的,
      与此相关的参数还有多个,详细情况请参考这篇文章jdk8 Metaspace 调优
      
-XX:HandlePromotionFailure:true   是否设置空间分配担保  JDK7及以后这个参数就失效了。
                               只要老年代的连续空间大于新生代对象的总大小或者历次晋升到老年代的对象的平均大小就进行MinorGC,否则FullGC。

1.堆设置
-Xms4G 是指: JVM启动时整个堆(包括年轻代,年老代)的初始化堆内存。  初始堆大小 默认为内存的(1/64)
-Xmx4G 是指: JVM启动时最大堆内存。    最大堆大小 默认为内存的(1/4)
-Xmn2G 是指: 新生代的内存,剩下的是年老代的内存大小, 值等于-Xmx减去-Xmn
-XX:NewRatio=2   年轻代/老年代  年轻的:老年代为 1:2
-XX:SurvivorRatio=1  是指:年轻代空间中2个Survivor空间与Eden空间的大小比例。此处为1:1:1,算法如下:比如整个年轻代空间为2G,如果比例为1,那么2/3,则S0/S1/Eden的空间大小是同样的,为666M。
    该值不设置,则JDK默认为比例为8,那么是1:1:8,通过上面的算法可以得出S0/S1的大小。
    我们可以看到官方通过增大Eden区的大小,来减少YGC发生的次数,但有时我们发现,虽然次数减少了,但Eden区满
    的时候,由于占用的空间较大,导致释放缓慢,此时stop-the-world的时间较长,因此需要按照程序情况去调优。
-XX:MetaspaceSize=128M   

2. 收集器设置
-XX:+UseConcMarkSweepGC 是指:使用CMS垃圾回收器。JDK1.7以后推荐使用G1垃圾收集器(Garbage First) -XX:+UseG1GC

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值