Java JVM 垃圾回收

一、垃圾回收作用于“堆”和“非堆(方法区)”两个线程共享的部分。

1、堆:

  堆的主要存放“生成的对象”和“开辟的数组”。

  面试的时候可能会问道,是不是所有的对象都存在于堆上?答案是否定的,当前虚拟机优化技术的发展,其中出现了逃逸分析(如果一个方法中生成的对象没有被其他方法或者线程使用,那么就是不逃逸的),如果对象不逃逸,那么就会把对象分配到栈空间上。另,网上有人还列举了TLAB,但是TLAB是存在于Eden之上的。

  

  如上图,我们来分析下对的组成,堆分为“Young(新生的)”和“Old(老年代)”两部分,其中Young中又分为一个“Eden”和两个“Survivor”。

  1)大部分“对象”会分配到Eden中,如果Eden空间不够用了,将会发起Minor GC,会将Eden中存活的对象和其中一个Survivor中存活并且没有晋升到Old的对象,复制到另一个Survivor中。

  如果Survivor中的空间不够用,将会将剩余的对象复制到Old区域中。(其中的限制,看4))

  注:任何时候,两个Survivor都只有一个被利用,且默认的时候Eden:Survivor=8:1。

  2)大对象(需要很长的连续空间,如很长的字符串、数组)直接分配到Old区域。

  3)在1)中,Minor GC之后,原先在Survivor的对象如果依旧在其中,那么他的”年龄“将会+1,如果年龄值>15(由-XX:MaxTenuringThreshold设置),将会晋升至Old区域。

  或者,在Survivor中相同年龄的对象占了其空间了一半以上,此时年龄大于前者的都会直接晋级到Old区域。

  4)以上晋升或者拷贝到Old区域的前提是,Old有足够的连续空间能容纳Young中所有对象的大小的情况;如果不够,将会在Old中进行Full GC。

2、非堆(方法区)

  方法区回收的主要动作是“常量池”清理和“类型卸载”

  1)常量池

 包括:常量,【类(接口)、方法、字符】的符号引用

 上述中,如果没有被引用,将可以被回收。

 2)类型卸载

 (1)不再存在实例

 (2)相应的ClassLoader被卸载

 (3)java.lang.Class对象不再引用,也即不再有反射操作。

 之后,就“可以”被回收。

二、附带复习下虚拟机运行时数据

  1、程序计数器

  2、Java虚拟机栈(线程私有,方法堆出即销毁)

    每个方法有会建立一个真栈,其中包括“局部变量表”,“操作数栈”,“动态链接”,“方法出口”等。

    其中局部变量表包括:

      1)基本数据类型,int long等

      2)对象的引用

      3)returnAddress类型

  3、本地方法栈(线程私有)被Native方法使用

  4、堆(会被垃圾回收)

  5、非堆(会被垃圾回收)

作者:林子木

博客地址:http://blog.csdn.net/wolinxuebin/

参考资料:《深入理解Java虚拟机》 周志明

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-07 08:36:35

Java JVM 垃圾回收的相关文章

java JVM垃圾回收机制

Java语言出来之前,大家都在拼命的写C或者C++的程序,而此时存在一个很大的矛盾,C++等语言创建对象要不断的去开辟空间,不用的时候有需要不断的去释放控件,既要写构造函数,又要写析构函数,很多时候都在重复的allocated,然后不停的~析构.于是,有人就提出,能不能写一段程序在实现这块功能,每次创建,释放控件的时候复用这段代码,而无需重复的书写呢? 1960年 基于MIT的Lisp首先提出了垃圾回收的概念,用于处理C语言等不停的析构操作,而这时Java还没有出世呢!所以实际上GC并不是Jav

深入理解Java之垃圾回收

概述 由于JVM中垃圾收集器的存在,使得Java程序员在开发过程中可以不用关心对象创建时的内存分配以及释放过程,当内存不足时,JVM会自动开启垃圾收集线程,进行垃圾对象的回收. 那么垃圾回收线程到底是什么时候触发,并如何实现垃圾回收的呢?本文将对openjdk的源码进行分析,并通过代码分析Java垃圾回收的过程. VMThread VMThread主要负责调度执行虚拟机内部的VM线程操作,如GC操作等,在JVM实例创建时进行初始化. VMThread::create() VMThread::cr

JVM垃圾回收机制总结(6) :透视Java的GC特性

1. 使用 System.gc() 可以不管JVM使用的是哪一种垃圾回收的算法,都可以请求 Java的垃圾回收. 在命令行中有一个参数-verbosegc可以查看Java使用的堆内存的情况,它的格式:java -verbosegc classfile class TestGC { public static void main(String[] args) { new TestGC(); System.gc(); System.runFinalization(); } } class TestG

Java的垃圾回收机制笔记

Java的垃圾回收机制笔记 java垃圾回收的意义 确保不再被引用的对象的内存空间被回收. 确保被引用的对象的内存不被错误回收. 再分配内存. java垃圾回收的常用方法 引用计数收集器 堆中的每个对象(不是对象的引用)都有一个引用计数.当一个对象被创建时,给该对象分配一个变量,该变量计数设置设置为1.当任何其他变量被赋值为这个对象的引用,计数加1(a=b,则b引用的对象计数+1),但当一个对象的某个引用超过生命周期或者被设置为一个新值的时候,引用的计数减1(a=c,则a不再指向b指向的对象,而

java的垃圾回收

此文为转载,但是笔者忘记转载自哪里,望原作者看见之后不要怪罪 1. 垃圾回收的意义 在C++中,对象所占的内存在程序结束运行之前一直被占用,在明确释放之前不能分配给其它对象:而在Java中,当没有对象引用指向原先分配给某个对象的内存时,该内存便成为垃圾.JVM的一个系统级线程会自动释放该内存块.垃圾回收意味着程序不再需要的对象是"无用信息",这些信息将被丢弃.当一个对象不再被引用的时候,内存回收它占领的空间,以便空间被后来的新对象使用.事实上,除了释放没用的对象,垃圾回收也可以清除内存

Java 的垃圾回收机制(转)

先看一段转载,原文出自 http://jefferent.iteye.com/blog/1123677 虚拟机中的共划分为三个代:年轻代(Young Generation).年老点(Old Generation)和持久代(Permanent Generation).其中持久代主要存放的是Java类的类信息,与垃圾收集要收集的Java对象关系不大.年轻代和年老代的划分是对垃圾收集影响比较大的. 年轻代: 所有新生成的对象首先都是放在年轻代的.年轻代的目标就是尽可能快速的收集掉那些生命周期短的对象.

java的垃圾回收机制的特点

浅谈java的垃圾回收机制的特点: 1.垃圾回收机制的目标是回收无用对象的内存空间(记住:不是对象),这些内存空间是JVM堆内存的内存空间.垃圾回收只回收内存资源,对于那些物理资源,如数据库连接,Socket,I/O流等资源无能无能为力,我们要自己关闭回收. 2.为了加快垃圾回收机制回收那些无用对象所占的内存空间,我们可以讲对象的引用变量置于null(记住:置于null后,垃圾回收机制不会立即执行的). 3.垃圾回收机制的潜在缺点它的开销会影响性能.Java虚拟机必须跟踪程序中有用的对象才可以确

全面解析Java的垃圾回收机制

转自:http://www.cnblogs.com/laoyangHJ/archive/2011/08/17/JavaGC.html —————————————————————————————————— Java的堆是一个运行时数据区,类的实例(对象)从中分配空间.Java虚拟机(JVM)的堆中储存着正在运行的应用程序所建立的所有对象,这些对象通过new.newarray.anewarray和multianewarray等指令建立,但是它们不需要程序代码来显式地释放.一般来说,堆的是由垃圾回收来

JVM垃圾回收算法 总结及汇总

先看一眼JVM虚拟机运行时的内存模型: 1.方法区 Perm(永久代.非堆) 2.虚拟机栈 3.本地方法栈 (Native方法) 4.堆 5.程序计数器 1 首先的问题是:jvm如何知道那些对象需要回收 ? 目前两种标识算法.三种回收算法.两种清除算法.三种收集器 引用计数法 每个对象上都有一个引用计数,对象每被引用一次,引用计数器就+1,对象引用被释放,引用计数器-1,直到对象的引用计数为0,对象就标识可以回收 这个可以用数据算法中的图形表示,对象A-对象B-对象C 都有引用,所以不会被回收,