JVM 系列-1:虚拟机内存管理

本节主要介绍的内容有:Java 虚拟机的内存划分、垃圾回收机制、虚拟机内存分析工具。

1、关于 Java

  1. Java 程序设计语言、Java 虚拟机、Java API 类库这三部分统称为 JDK,JDK 是用于支持 Java 程序开发的最小环境。
  2. Java API 类库中的 Java SE API 子集和 Java 虚拟机这两部分统称为 JRE,JRE 是支持 Java 程序运行的标准环境。
  3. HotSpot 是目前使用最为广泛的虚拟机。

Java以后发展的几个方向:

  1. 模块化,功能组件可插拔;
  2. 混合语言:各不同的功能模块使用不同的运行在虚拟机之上的语言开发;
  3. 多核并行:使用分治算法等提升多核利用率;
  4. 丰富现有的语法;
  5. 解决 64 位虚拟机上的性能问题。

2、JVM 内存管理

2.1 JVM 内存区域

下图是 Java 虚拟机的内存主要区域划分,注意图中由浅蓝色标识的部分是所有线程共享的数据区;淡紫色标识的部分是每个线程私有的数据区域

虚拟机内存区域

我们这里对各个部分功能做简要的总结:

  1. 程序计数器线程私有,用来指示当前线程所执行的字节码的行号,就是用来标记线程现在执行的代码的位置;对 Java 方法,它存储的是字节码指令的地址;对于 Native 方法,该计数器的值为空。
  2. 线程私有,与线程同时创建,总数与线程关联,代表Java方法执行的内存模型。每个方法执行时都会创建一个栈桢来存储方法的的变量表、操作数栈、动态链接方法、返回值、返回地址等信息。一个方法的执行和退出就是用一个栈帧的入栈和出栈表示的。通常我们不允许你使用递归就是因为,方法就是一个栈,太多的方法只执行而没有退出就会导致栈溢出,不过可以通过尾递归优化。栈又分为虚拟机栈和本地方法栈,一个对应 Java 方法,一个对应 Native 方法。
  3. :用来给对象分配内存的,几乎所有的对象实例(包括数组)都在上面分配。它是垃圾收集器的主要管理区域,因此也叫 GC 堆。它实际上是一块内存区域,由于一些收集算法的原因,又将其细化分为新生代和老年代等。如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出 OutOfMemoryError 异常。
  4. 方法区:方法区由多线程共享,用来存储类信息、常量、静态变量、即使编译后的代码等数据。运行时常量池是方法区的一部分,它用于存放编译器生成的各种字面量和符号引用,比如字符串常量等。根据 Java 虚拟机规范的规定,当方法区无法满足内存分配需求时,将抛出 OutOfMemoryError 异常。

2.2 垃圾回收

根据上面 JVM 内存区域的描述,因为程序计数器和两种栈的生命周期与线程相同,线程或者方法结束即可回收。所以,所谓的垃圾回收主要是针对方法区和堆内存而言。

生存还是死亡?

可达性分析 四种引用类型 对象的自我救赎

判断一个对象是否可以回收通用的方式有两种。

  1. 一种是引用记数法,即给对象添加一个引用计数器,被引用时计数器加1,引用失效时减1。
    这种方法不常用,因为它难以解决两个变量相互引用的问题。
  2. 另一种是可达性分析,即通过一系列 GC Roots 的对象作为起始点,从节点向下搜索,
    当一个对象没有任何一条可到 GC Roots 的引用链,则该对象可回收。

根据可达性分析的原理,对象之间存在引用关系,但是 “是或否被引用” 不足以描述更多的场景,
所以在这基础之上人们又提出了四种引用类型的概念:强引用、软引用、弱引用和虚引用,它们的引用强度依次减弱。

  1. 当使用 new 关键字创建一个对象的时候,这个对象就是强引用的,它绝对不会被回收,即使内存
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值