深入理解_JVM内存管理对象引用03

1、对象引用:

(a)对象状态的判断:

<1> 引用计数算法:无法解决对象相互引用的问题。

<2> 根搜索算法:主流的判断对象是否存活的算法。

(1)基本思路:通过一系列的名为:“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相关联时,证明此对象是不可用的,所以它们将会被判断为是可收回的对象。

(2)Java中,GC Roots的对象包括下面几种:

a:虚拟机栈(栈帧中的本地变量表)中的引用的对象;

b:方法区中的类静态属性引用的对象;

c:方法区中的常量引用的对象;

d:本地方法栈JNI(Native方法)的引用的对象。

(3) GC Roots对象结构图,如下图:

(b) Java1.2之后,Java重新定义了对象的引用:

对象引用类型分为 强引用、软引用、弱引用和虚引用。

强引用: 就是我们一般声明对象是时虚拟机生成的引用,如:Object obj=new Object() 。强引用环境下,垃圾回收时需要严格判断当前对象是否被强引用,如果被强引用,则不会被垃圾回收。

软引用: 软引用一般被做为缓存来使用。与强引用的区别是,软引用在垃圾回收时,虚拟机会根据当前系统的剩余内存来决定是否对软引用进行回收。如果剩余内存比较紧张,则虚拟机会回收软引用所引用的空间;如果剩余内存相对富裕,则不会进行回收。换句话说,虚拟机在发生OutOfMemory时,肯定是没有软引用存在的。存活时间可通过-XX:SoftRefLRUPolicyMSPerMB来进行控制。

弱引用: 弱引用与软引用类似,都是作为缓存来使用。但与软引用不同,弱引用在进行垃圾回收时,是一定会被回收掉的,因此其生命周期只存在于一个垃圾回收周期内。

虚引用:一个对象是否有虚引用的存在,完全不会对其生存时间构成影响,也无法通过虚引用来获取一个对象实例。唯一的目的:希望能在这个对象被搜集器回收时收到一个系统通知。

总结:

强引用不用说,我们系统一般在使用时都是用的强引用。而“软引用”和“弱引用”比较少见。他们一般被作为缓存使用,而且一般是在内存大小比较受限的情况下做为缓存。常见的是被使用在桌面应用系统的缓存。

(c)生存或者死亡?

在根算法不可达的对象,也并非是“非死不可”的。至少需要经历2次标记过程:

<1> 如果对象在进行根算法搜索之后,发现没有与GC Roots相连接的引用链,它将会第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法。

<2> 如果该对象有必须执行finalize()方法,将会被放置在一个F-Queue的队列中,稍后由一条虚拟机自动建立的,低优先级的Finalizer线程去执行(执行即为触发该方法)。

<3> finalize()方法是对象逃脱死亡的最后一次机会,稍后GC将对F-Queue中的对象进行第二次小规模的标记,如果对象要在finalize()中成功拯救自己——只要重新与引用链上的任何一个对象建立关联即可。

(d)回收方法区:

很多人认为方法区(或HotSpot虚拟机中的持久代)是没有垃圾回收的。

实际上是有的,只是垃圾收集的效率很低。

永久代的垃圾收集主要回收2部分内容:废弃常量和无用的类。

<1> 回收废弃常量与回收Java堆中的对象非常类似:当常量无任何引用,如果此时发生内存回收,这个常量被系统请出常量池。常量池中的其他类(接口)、方法、字段的符号引用也与此类似。

<2> 回收无用的类的条件比较苛刻。类必须要同时满足以下3个条件才能算是“无用的类”:

(1) 该类的所有实例都已被回收,即java堆中不存在该类的任何实例。

(2) 加载该类的ClassLoader已经被回收。

(3) 该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。

满足上述条件之后,类可能被回收。那是否被回收,HotSpot提供下列参数进行控制:

(1)是否被回收:-Xnoclassgc参数来进行控制。

(2)查看类的加载信息:-verbose:class及-XX:+TraceClassLoading(可以再product版的虚拟机中使用)。

(3)查看类的卸载信息:-verbose:class及-XX:+TraceClassUnLoading(需要fastdebug版的虚拟机支持)。

时间: 2024-10-11 07:44:02

深入理解_JVM内存管理对象引用03的相关文章

深入理解_JVM内存管理调优案例分析与实战10

1.高性能硬件上的程序部署策略 目前常用2种方式: (1)通过64位JDK来使用大内存: 使用第一种方式关键: <1>控制应用程序的Full GC频率.譬如10多个小时甚至一天才出现一次Full GC. 关键:大多数对象的生存时间不应该太长,保证老年代空间的稳定. 在大多数网站形势的应用里,主要对象的生存周期都是请求级或页面级的,会话级和全局级的长生命对象相对较少,控制住Full GC. 需要考虑的问题: <1>内存回收导致的长时间停顿: <2>现阶段,64位JDK的性

深入理解_JVM内存管理内存分配和回收策略06

解决两个问题: 1.对象分配内存: 2.回收分配给对象的内存. 本节详细讲解分配的问题: 名词解释: 新生代GC(Minor GC):指发生在新生代的垃圾回收动作,非常频繁,回收速度很快. 老生代GC(Major GC/Full GC):指发生在老生代的垃圾回收动作,出现了Major GC,经常会伴随至少一次的Minor GC(但非绝对),速度一般会比Minor GC慢10倍. 打印日志说明: <1> DefNew:串行GC方式(Serial GC). <2> ParNew:Par

深入理解_JVM内存管理JDK监控工具与故障处理工具07

1.jps: JVM process Status Tool,显示系统所有的HotSpot虚拟机进程以及进程的本地虚拟机的唯一ID(LVMID,Local Virtual Machine Identifier). 对于本地虚拟机进程来说,LVMID与操作系统的进程ID(PID,Process Identifier)是一致的.如果启动了多个虚拟机进程,就需要显示主类的功能才能区分了. jps命令格式: jps [option] [hostid] jps主要选项: -v :输出虚拟机进程启动时JVM

深入理解_JVM内存管理JDK监控工具与故障处理工具08

Jconsole: Visial VM: 1.主要功能: (1)显示虚拟机进程及进程的配置和环境信息(jps,jinfo): (2)监视应用程序的CPU.GC.堆.方法区及线程信息(jstat,jstack): (3)dump及分析堆转储快照(jmap,jhat): (4)方法级的程序运行性能分析,找出被调用最多.运行时间最长的方法: (5)离线程序快照:收集程序的运行时配.线程dump.内存dump等信息建立一个快照,可以将快照发送开发者进行bug处理: (6)其他plus可能性. 2.生成和

深入理解_JVM内存管理垃圾收集算法04

1.垃圾收集算法(方法论): 定义:JVM通过GC来回收堆和方法区中的内存. GC的基本原理:首先会找程序中不再被使用的对象:然后回收这些对象所占用的内存. 算法分类: (1) 按照基本回收策略分: <1>引用计数(Reference Counting): 比较古老的回收算法.原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数.垃圾回收时,只用收集计数为0的对象.此算法最致命的是无法处理循环引用的问题. <2> 标记-清除(Mark-Sweep): Before G

深入理解_JVM内存管理典型配置举例09

以下配置主要针对分代垃圾回收算法而言: 1.堆大小设置: 年轻代的设置很关键JVM中最大堆大小有三方面限制: (1)相关操作系统的数据模型(32-bt还是64-bit)限制: (2)系统的可用虚拟内存限制: (3)系统的可用物理内存限制.32位系统下,一般限制在1.5G~2G:64为操作系统对内存无限制.在Windows Server 2003 系统,3.5G物理内存,JDK5.0下测试,最大可设置为1478m. 典型设置: (1)场景一: java -Xmx3550m -Xms3550m -X

深入理解_JVM内存管理垃圾收集器05

1.垃圾收集器(内存回收方法的具体实现): 名词解释: 并行(Parallel):多条垃圾线程并行工作,但是此时用户线程仍然处于等待状态. 并发(Concurrent):指用户线程与垃圾收集线程同时执行(并不一定是并行的,可能会交替执行),用户程序继续运行,而垃圾收集程序运行于另一个CPU上. HotSpot虚拟机包含的所有收集器如下图: 说明: (a)JDK1.6_Update14之后引入了Early Access版G1收集器. (b)如果两个收集器之间存在连线,就说明它们可以搭配使用. <Y

你应该这样理解JVM内存管理

在进行Java程序设计时,一般不涉及内存的分配和内存回收的相关代码,此处引用一句话: Java和C++之间存在一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外的人想进去,墙里面的人想出来 ,个人从这两句话中,捕获到了 两个点 . java的自动内存管理机制,极大的节省了开发人员的精力,避免了易错且复杂的内存管理设计,相对于手动的内存管理这是极大的飞跃.java自动内存管理机制,其不能根据具体的场景提供最优的内存管理,其只提供普适的内存管理机制.想比于C++的手动内存管理,灵活性不够,存在制约系

深入理解Linux内存管理

引用:Live and Learn 1. 内存地址 以Intel的中央处理器为例,Linux 32位的系统中,物理内存的基本单位是字节(Byte),1个字节有8个二进制位.每个内存地址指向一个字节,内存地址加1后得到下一个字节的地址.这里用以表示物理内存实际位置的地址,就是通常所说的物理地址(Physical Address).CPU正在执行的进程代码.进程数据和栈区数据等,都临时保存在物理内存中. 线性地址(Linear Address,亦即虚拟地址 Virtual Address)是出于以下