JVM垃圾回收总结详解(一)细心阅读

Java内存大体分为:堆内存(Heap) 栈内存(Stack)
内存细分:
虚拟机栈
本地方法栈
PC寄存器
方法区
堆区

再分:
线程共享区:方法区,堆区。随着虚拟机启动而创建,随着虚拟机退出而销毁,并且为进程的所有子线程共享
线程独享区:虚拟机栈,本地方法栈,PC寄存器,这些数据与线程一一对应,这些与线程对应的数据区域会随着线程开始和结束而创建和销毁
在这里插入图片描述

一 、线程独享区
PC寄存器:任意时刻,一个虚拟机线程只会执行一个方法的代码,这个正在被执行的方法被称为线程的当前方法,而PC寄存器存储的就是当前方法经过JVM汇编的后字节码指令的地址
虚拟机栈:栈中元素叫做栈帧,线程再调用Java方法时,会为每个方法创建一个栈帧。栈帧:存储局部变量表、操作栈、动态链接、方法出口等信息。每个方法被调用和完成的过程,都对应着一个栈帧从虚拟机栈上入栈和出栈的过程。生命周期:虚拟机栈与线程同步。栈帧( Frame)是用来存储数据和部分过程结果的数据结构在这里插入图片描述

本地方法栈:Java 虚拟机实现可能会使用到传统的栈(通常称之为“ C Stacks”)来支持 native 方法( 指使用 Java 以外的其他语言编写的方法)的执行,这个栈就是本地方法栈( Native Method Stack)。当 Java 虚拟机使用其他语言(例如 C 语言)来实现指令集解释器时,也会使用到本地方法栈。本地方法栈和虚拟机栈所发挥的作用是非常相似的,区别是虚拟机栈执行Java方法,而本地方法栈则为虚拟机使用的Native方法服务,在sun hotspot 虚拟机中已经把两者合二为一了,本地方法栈区也会抛出StackOverFlowError和OutOfMemeoryError异常

二 、线程共享区
Heap:
Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此区域唯一目的就是存放对象实例,几乎所有对象的实例都在这分配内存。Java堆是垃圾收集器管理的主要区域,因此很多时候也被称为GC堆,Java 堆在虚拟机启动的时候就被创建,它存储了被自动内存管理系统( Automatic Storage Management System,也即是常说的“ Garbage Collector(垃圾收集器)”)所管理的各种对象。 Java 堆的容量可以是固定大小的,也可以随着程序执行的需求动态扩展,并在不需要过多空间时自动收缩

方法区:它存储了每一个类的结构信息,例如运行时常量池( Runtime Constant Pool)、字段和方法数据、构造函数和普通方法的字节码内容、还包括一些在类、实例、接口初始化时用到的特殊方法。方法区是堆的逻辑组成部分
在这里插入图片描述

JVM布局:
在这里插入图片描述

每一个运行再JAVA虚拟机里的线程都拥有自己的线程栈,这个线程栈包含了这个线程调用的方法当前执行点相关的信息
堆上包含在Java程序中创建的所有对象,无论是哪一个对象创建的。这包括原始类型的对象版本。如果一个对象被创建然后赋值给一个局部变量,或者用来作为另一个对象的成员变量,这个对象任然是存放在堆上。

变量:
1、成员变量(实例变量,属性)
2、本地变量(局部变量)
3、类变量(静态属性)
仅有本地变量放在线程栈上

从JVM运行时内存进行划分:堆内存和非堆内存
堆内存:堆试运行时数据区域,所有实例和数组的内存均从此处分配。堆实在JAVA虚拟机启动时创建的,
非堆内存:再JVM中堆之外的内存称为非堆内存(non-heap)

从对象的角度来说JVM内存大致分为3块:
Permanent Generation: 持久代
New Generation :年轻代
Tenured Geneeation :老年代

持久带位于:non-heap区
new和old是Java应用的Heap区用来存放类的实例Instance的
在这里插入图片描述

new 尽可能快速的手机哪些生命周期短的的对象:
eden space --> from survivor space -> to survivor space ->
当To也满了就从From区复制过来并且依然存货的对象到Old区,从而From和To救助空间互换角色,维持活动的对象将在救助空间不断复制,直到最终转入Old域。需要注意,Survivor的两个区是对称的,没先后关系,所以同一个区中可能同时存在从Eden复制过来对象,和从前一个Survivor复制过来的对象,而且,Survivor区总有一个是空的。同时,根据程序需要,Survivor区是可以配置为多个的(多于两个),这样可以增加对象在年轻代中的存在时间,减少被放到年老代的可能。每一次垃圾回收后,Eden Space都会被清空。

Old区用于存放长寿的对象,在New区中经历了N次垃圾回收后仍然存活的对象,就会被放到Old区中;如那些与业务信息相关的对象,包括Http请求中的Session对象、线程、Socket连接,这类对象跟业务直接挂钩,因此生命周期比较长。

以上任何一个空间不够时都会促进jvm执行垃圾回收,基于类型不同,我们将垃圾回收分为:
Minor GC(young gc): 回收new Generation内存空间(eden , from to )
Full GC(): 回收new Generation和Tenured Generation、PermGen内存空间

  1. Minor GC(young gc)
    当新对象生成,并且在Eden申请空间失败时,就会触发Minor GC,对Eden区域进行GC,清除非存活对象,并且把尚且存活的对象移动到Survivor区,然后整理Survivor的两个区。这种方式的GC是对New区的Eden区进行,不会影响到Old区。因为大部分对象都是从Eden区开始的,同时Eden区不会分配的很大,所以Eden区的Minor GC会频繁进行。一般在这里需要使用速度快、效率高的算法,使Eden去能尽快空闲出来。

  2. Full GC
    Full GC要对整个Heap区进行回收,包括New、Old和PermGen,所以比Minor GC要慢,因此应该尽可能减少Full GC的次数。在对JVM性能调优的过程中,很大一部分工作就是对于Full GC的调节。有如下原因可能导致Full GC:
    ·Tenured区被写满
    ·PermGen区被写满
    ·System.gc()被显示调用
    ·上一次GC之后Heap的各域分配策略动态变化
    需要注意的是,Full GC与YoungGC是无法完全区分开来的,很多情况下,Full GC是由YoungGC导致的。例如在Eden Space中的对象经历过几次垃圾回收,依然还存活,就会移动到Tenured区,而如果此时Tenured区空间不够,就会出发垃圾回收,过程如下图所示:
    在这里插入图片描述

survivor space:其实是临时存储空间,几次垃圾回收依然没回收掉的对象被过渡到老年代

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值