java内存Young Generation基本认识

一、Java内存的构成

  先贴原图


 如图可知:整块区域分为Young Generation、Tenured Generation(年轻代→老年代 )(j在于JDK8中把存放元数据中的永久内存从堆内存中移到了本地内存(native memory)中)

 

咱们看下Young区:

    Young区又分为:Eden、Survivor Space。

    Survivor Space又分为 To Survivor、 From Survivor,如下图所示:

      Eden和Survivor的比例是8:1:1

 


 

 

 

Survivor Space存在的意义:

 首先说如果没有Survivor区会出现什么情况:此时每触发一次Minor GC,就会把Eden区的对象复制到老年代,这样当老年代满了之后会触发Major Gc(通常伴随着MinorGC,可以看做Full GC),比较耗时。

如果只有1个Survivor区,那当Eden区满了之后,就会复制对象到Survivor区,容易产生内存碎片化。严重影响性能。
所以使用2个Survivor区,始终保持有一个空的Survivor区,可以避免内存碎片化。

 

 

Java内存分为 堆内存(heap)和 Permanent区。

1、Java堆内存(heap):

    --是 JVM 用于分配 Java对象的内存,包含活动对象和不可用对象 

    --堆大小通常是在服务器启动时使用 java命令中的 –Xms(最小) –Xmx(最大)标志来定义。 

2、Permanent区:

    --指内存的永久保存区域

    --是Sun JDK和HPJDK用来加载类(class)和Meta信息的专门的内存区

   --这个区域不归属Java堆内存(heap)范围

   --Class在被Loader时就会被放到此,如果Java应用很大,例如类(class)很多,那么建议增大这个区域的大小来满足加载这些类的内存需求

    --通过–XX:PermSize=***M–XX:MaxPermSize=***M调整

 

这里还有一个本地内存的概念:

·本地内存(native memory): 

    --是 JVM用于其内部操作的本地内存(非Java内存) 

    --JNI 代码和第三方本地模块(例如,本地JDBC 驱动程序)也使用本地内存 

   --最大本地内存大小取决于以下因素:操作系统进程内存大小限制、已经指定用于 Java 堆的内存

 

也就是说,整个物理机的内存可以说由以下部分构成:

物理内存 = Java 内存 + 本地内存 + 操作系统保留的内存

 

 

二、垃圾回收(Garbage Collection,GC)

 

1、为什么要垃圾回收

   --JVM自动检测和释放不再使用的内存。 

    --Java 运行时JVM会执行GC,这样程序员不再需要显式释放对象。 

 

2、垃圾回收(GC)的分类

    --Minor GC

    --Full GC

 

3、垃圾回收(GC)的产生过程

   新生成的对象在Eden区完成内存分配

  1.     当Eden区满了,再创建对象,会因为申请不到空间,触发minor GC,进行young(eden+From survivor)区的垃圾回收。(为什么是eden+From survivor:两个survivor中始终有一个survivor是空的,空的那个被标记成To Survivor)
  2.   minorGC时,Eden不能被回收的对象被 复制 到空的survivor(也就是放到ToSurvivor,同时Eden肯定会被清空),另一个survivor(From Survivor)里不能被GC回收的对象也会被  复制    到这个survivor(To Survivor),始终保证一个survivor是空的。(MinorGC完成之后,To Survivor 和 From Survivor的标记互换)
  3.   当做第3步的时候,如果发现存放对象的那个survivor满了,则这些对象被copy到old区,或者survivor区没有满,但是有些对象已经足够Old(通过XX:MaxTenuringThreshold参数来设置)默认是 15 岁,这些对象就会成为老年代。 
    但这也不是一定的,对于一些较大的对象 ( 即需要分配一块较大的连续内存空间 ) 则是直接进入到老年代。
  4.    当Old区被放满的之后,进行完整的垃圾回收,即 Full GC
  5.     FullGC时,整理的是Old Generation里的对象,把存活的对象放入到Permanent Generation里。

 

4.好了看下Minor GC、Major GC和Full GC之间的区别:

  1)Minor GC:年轻代的回收过程称为 Minor GC

  1. 当 JVM 无法为一个新的对象分配空间时会触发 Minor GC,比如当 Eden 区满了。所以分配率越高,越频繁执行 Minor GC。
  2. 内存池被填满的时候,其中的内容全部会被复制,指针会从0开始跟踪空闲内存。Eden 和 Survivor 区进行了标记和复制操作,取代了经典的标记、扫描、压缩、清理操作。所以 Eden 和 Survivor 区不存在内存碎片。写指针总是停留在所使用内存池的顶部。
  3. 执行 Minor GC 操作时,不会影响到永久代。从永久代到年轻代的引用被当成 GC roots,从年轻代到永久代的引用在标记阶段被直接忽略掉。
  4. 质疑常规的认知,所有的 Minor GC 都会触发“全世界的暂停(stop-the-world)”,停止应用程序的线程。对于大部分应用程序,停顿导致的延迟都是可以忽略不计的。其中的真相就 是,大部分 Eden 区中的对象都能被认为是垃圾,永远也不会被复制到 Survivor 区或者老年代空间。如果正好相反,Eden 区大部分新生对象不符合 GC 条件,Minor GC 执行时暂停的时间将会长很多

2)Major GC vs Full GC

  1. Major GC 是清理老年代。
  2. Full GC 是清理整个堆空间—包括年轻代和老年代。
  3. 首先,许多 Major GC 是由 Minor GC 触发的,所以很多情况下将这两种 GC 分离是不太可能的。另一方面,许多现代垃圾收集机制会清理部分永久代空间,所以使用“cleaning”一词只是部分正确。

5、垃圾回收的回收器

  --串行(–XX:+UseSerialGC )

    Out ofBox算法,年轻代串行复制,年老代串行标记整理,主要用于桌面应用

 

  --并行(–XX:+UseParallelGC )

    年轻代暂停应用程序,多个垃圾收集线程并行的复制收集,年老代暂停应用程序,与串行收集器一样,单垃圾收集线程标记整理。JDK6.0启用该算法后,默认启用了-XX:+UseParallelOldGC,性能大为提高

 

  --并发(Concurrent Low Pause Collector)(–XX:+UseConcMarkSweepGC )

    启用该参数,默认启用了-XX:+UseParNewGC;简单的说,并发是指用户线程与垃圾收集线程并发,程序在继续运行,而垃圾收集程序运行于其他CPU上。

 

---------第一次写 比较乱~有不对的还望指正

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值