JVM 内存结构(一)

1、JVM 内存结构图

 
了解JVM优化,先搞清楚JVM 的内存结构,以下为JVM 内存结构图。
请添加图片描述

 

2、堆内存(Heap)

 

2.1、堆内存结构

 
请添加图片描述

  • 堆内存的新生代分为Eden(伊甸园)和存活区(survivor),Survivor区由 FromSpace 和 ToSpace 组成。Eden区占大容量,Survivor两个区占小容量,默认比例是8:1:1。

  • JVM只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身.

  • 堆内存用途:存放的是对象,垃圾收集器就是收集这些对象,然后根据 GC(垃圾回收)算法回收。

  • JDK8 版本废弃了永久代,替代的是元空间(MetaSpace)。元空间与持久代(Perm Gen)类似,都是方法区的实现。两者最大区别是:元空间并不在 JVM 中,而是使用本地内存。

元空间有注意有两个参数:

  • MetaspaceSize :初始化元空间大小,控制发生GC阈值。
  • MaxMetaspaceSize : 限制元空间大小上限,防止异常占用过多物理内存。

 

2.2、新生代 && 老年代 && 持久代

 

  1. 新生成的对象,首先放到新生代的伊甸园(Eden)区,当Eden区空间满了,触发 Minor GC(清理新生代),存活下来的对象移动到 Survivor0(即From Survivor)区。
  2. Survivor0 区满后触发执行 Minor GC(清理新生代),Survivor0 区存活对象移动到 Survivor1(即To Survivor) 区。
  3. JVM 每次只会使用 Eden 和其中的一块 Survivor 区域来为对象服务 ,所以 无论什么时候,总是有一块Survivor区域是空闲着的如此就保证了一段时间内总有一个 幸存区(Survivor)为空。所以新生代实际可用的内存空间为 9/10 ( 即90% )的新生代空间
  4. 经过多次 Minor GC(清理新生代)仍然存活的对象移动到老年代(Tenured)。

 

  • 堆大小 = 新生代 + 老年代。其中,堆的大小可以通过参数 –Xms、-Xmx 来指定。
  • 默认的,新生代 ( Young ) 与老年代 ( Old ) 的比例的值为 1:2 ( 该值可以通过参数 –XX:NewRatio 来指定 )
  • 默认的,Eden : from Survivor : to Survivor = 8 :1 : 1 ( 可以通过参数–XX:SurvivorRatio来设定 ),即: Eden = 8/10 的新生代空间大小,from Survivor = to Survivor = 1/10 的新生代空间大小

 

2.3、扩展说明 GC

 

  • Java 中的堆Heap 是 GC (垃圾回收)的主要区域

  • GC 分为两种:Minor GC、Full GC ( 或称为 Major GC )。

  • Minor GC发生在新生代中的垃圾收集动作,所采用的是复制算法

  • Full GC发生在老年代 的垃圾收集动作,所采用的是标记-清除算法。Full GC 发生的次数不会有 Minor GC 那么频繁,并且做一次 Full GC 要比进行一次 Minor GC 的时间更长。

 

2.4、JVM 参考选项

 

项目说明
-Xms初始堆大小,单位m、g。如:-Xms256m
-Xmx(MaxHeapSize)最大堆大小,一般不要大于物理内存的80% ,如:-Xmx512m
-XX:MaxNewSize(-Xmn)新生代大小。通常为 Xmx 的 1/3 或 1/4。新生代 = Eden + 2 个 Survivor 空间。实际可用空间为 = Eden + 1 个 Survivor,即 90% .
-Xss表示堆栈内存大小。JDK1.5+ 每个线程堆栈大小为 1M,一般来说如果栈不是很深的话, 1M 是绝对够用了的。
-XX:NewRatio新生代与老年代的比例,如 –XX:NewRatio=2,则新生代占整个堆空间的1/3,老年代占2/3.
-XX:SurvivorRatio新生代中 Eden 与 Survivor 的比值,默认值为 8。即 Eden 占新生代空间的 8/10,另外两个 Survivor 各占 1/10
-XX:PermSize永久代(方法区)的初始大小。一般应用设置初始化200m,最大1024m就够了。
-XX:MaxPermSize永久代(方法区)的最大值
-XX:+PrintGCDetails打印 GC 信息

 

3、栈内存(Stack)

 

  • 虚拟机栈虚拟机栈也是线程私有的,生命周期与线程相同主要存储基本数据类型(boolean、byte、、char、short、int、float、long、double)、对象引用 (reference类型,它不等同于对象本身。可能是一个对象起始地址的引用指针,也可能指向代表一个对象的句柄或者此对象的相关位置) 和 returnAddress 类型(指向了一条字节码指令的地址)。目前大多数虚拟机可动态扩展,如果扩展时无法申请到足够的内存即会抛出 OutOffMemoryError 异常。

 

  • 本地方法栈与虚拟机栈作用是相似的,他们之间的区别是,虚拟机栈用来执行java方法(也就是字节码),而本地方法栈则为虚拟使用到的 native (用来修饰可供其他语言调用的方法,如操作操作系统底层服务的方法)服务,部分虚拟机(譬如 sun HotSpot) 直接将虚拟栈和本地方法栈合二为一,与java虚拟机栈相同,也会抛出OutOffMemoryError异常。

 

4、方法区内存

 

请添加图片描述

 

  • 方法区又叫静态区,跟堆一样,被所有的线程共享。
  • 方法区用于存储虚拟机加在的类信息、常量、static静态变量、即时编译器编译后的代码等数据。虽然java虚拟机把他标注为堆的一部分,但他也有一个别名“非堆”,用于与java堆区分。

 

  • 静态常量池:也被称为 class文件常量池。 主要存放:
    1、字面量:例如文本字符串,final修饰的常量。
    2、符号引用:例如类和接口的全限定名,字段的名称和描述符,方法的名称和描述符等。
     
  • 运行时常量池:当类加载到内存中后,JVM 就会将静态常量池中的内容存放到运行时的常量池中,运行时常量池里面存储的主要是编译期间生成的字面量、符合引用等等
     
  • 字符串常量池:其可以理解成运行时常量池分出来的一部分,类加载到内存的时候,字符串会存到字符常量池里面。

 
 
 
 
 
 
 
 
 
 
.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值