JVM/GC 原理

一、JVM结构

JVM主要包括四个部分:

1.类加载器(ClassLoader):在JVM启动时或者在类运行时将需要的class加载到JVM中。

2.执行引擎:负责执行class文件中包含的字节码指令(执行引擎的工作机制,这里也不细说了,这里主要介绍JVM结构);

3.内存区(也叫运行时数据区):是在JVM运行的时候操作所分配的内存区。运行时内存区主要可以划分为5个区域,如图:

  • 方法区(Method Area):用于存储类结构信息的地方,包括常量池、静态变量、构造函数等。虽然JVM规范把方法区描述为堆的一个逻辑部分, 但它却有个别名non-heap(非堆),所以大家不要搞混淆了。方法区还包含一个运行时常量池。
  • java堆(Heap):存储java实例或者对象的地方。这块是GC的主要区域。从存储的内容我们可以很容易知道,方法区和堆是被所有java线程共享的。
  • java栈(Stack):java栈总是和线程关联在一起,每当创建一个线程时,JVM就会为这个线程创建一个对应的java栈。在这个java栈中又会包含多个栈帧,每运行一个方法就创建一个栈帧,用于存储局部变量表、操作栈、方法返回值等。每一个方法从调用直至执行完成的过程,就对应一个栈帧在java栈中入栈到出栈的过程。所以java栈是现成私有的。
  • 程序计数器(PC Register):用于保存当前线程执行的内存地址。由于JVM程序是多线程执行的(线程轮流切换),所以为了保证线程切换回来后,还能恢复到原先状态,就需要一个独立的计数器,记录之前中断的地方,可见程序计数器也是线程私有的。
  • 本地方法栈(Native Method Stack):和java栈的作用差不多,只不过是为JVM使用到的native方法服务的。

二、内存分配

我觉得了解垃圾回收之前,得先了解JVM是怎么分配内存的,然后识别哪些内存是垃圾需要回收,最后才是用什么方式回收。

Java的内存分配原理与C/C++不同,C/C++每次申请内存时都要malloc进行系统调用,而系统调用发生在内核空间,每次都要中断进行切换,这需要一定的开销,而Java虚拟机是先一次性分配一块较大的空间,然后每次new时都在该空间上进行分配和释放,减少了系统调用的次数,节省了一定的开销,这有点类似于内存池的概念;二是有了这块空间过后,如何进行分配和回收就跟GC机制有关了。

java一般内存申请有两种:静态内存和动态内存。很容易理解,编译时就能够确定的内存就是静态内存,即内存是固定的,系统一次性分配,比如int类型变量;动态内存分配就是在程序执行时才知道要分配的存储空间大小,比如java对象的内存空间。根据上面我们知道,java栈、程序计数器、本地方法栈都是线程私有的,线程生就生,线程灭就灭,栈中的栈帧随着方法的结束也会撤销,内存自然就跟着回收了。所以这几个区域的内存分配与回收是确定的,我们不需要管的。但是java堆和方法区则不一样,我们只有在程序运行期间才知道会创建哪些对象,所以这部分内存的分配和回收都是动态的。一般我们所说的垃圾回收也是针对的这一部分。

总之Stack的内存管理是顺序分配的,而且定长,不存在内存回收问题;而Heap 则是为java对象的实例随机分配内存,不定长度,所以存在内存分配和回收的问题;

三、垃圾检测、回收算法

时间: 06-20

JVM/GC 原理的相关文章

Java性能优化之JVM GC(垃圾回收机制)

Java的性能优化,整理出一篇文章,供以后温故知新. JVM GC(垃圾回收机制) 在学习Java GC 之前,我们需要记住一个单词:stop-the-world .它会在任何一种GC算法中发生.stop-the-world 意味着JVM因为需要执行GC而停止了应用程序的执行.当stop-the-world 发生时,除GC所需的线程外,所有的线程都进入等待状态,直到GC任务完成.GC优化很多时候就是减少stop-the-world 的发生. JVM GC回收哪个区域内的垃圾? 需要注意的是,JV

JVM GC调优一则--增大Eden Space提高性能

缘起 线上有Tomcat升级到7.0.52版,然后有应用的JVM FullGC变频繁,在高峰期socket连接数,Cpu使用率都暴增. 思路 思路是Tomcat本身的代码应该是没有问题的,有问题的可能是应用代码升级,或者环境改变了,总之Tomcat的优先级排在最后. 先把应用的heap dump下来分析下: jmap -dump:format=b,file=path pid 用IBM的Heap Analyser分析,发现dubbo rpc调用的RpcInvocation对象和taglibs的Si

java内功 ---- jvm虚拟机原理总结,侧重于GC

写作日期 2016-08-22-23 交流qq:992591601 参考资料:<深入理解java虚拟机>.<thinking in java>.<Effective Java> 直接从最要紧的地方讲,Java GC算法.需说明一点,GC机制只是涉及堆内存的.因为堆内存是动态的,在程序运行期间分配的. 一.判断什么需要被回收: 1.引用计数法 问题在于两个对象互相引用,然后各种指向null.堆内存中的对象是不会被回收的. 上图是体现一种变化,绘画技巧不行,用绿框表示对象成

JS疑难点和GC原理

1. JS中的typeof是一元操作符,不是函数 在chrome的Console控制台上,输入typeof null,它会输出"object".因此,使用typeof操作符的时候,除了null,都会识别出其他数据的类型. 2. JS中的instanceof来区分Object下的Array.Json.RegEx.Date.Function.Error.Math instanceof对于非对象,返回false instanceof对于原型链上的对象,返回原型链对象 3. Object转St

JVM GC之一找出不可达对象并回收

JAVA运行时数据区域 1.程序计数器:当前线程所执行的字节码的行号指示器.一个处理器只会执行一条线程中的指令,为了线程切换后能回复到正确的执行位置,所以每条线程都需要一个独立的计数器.各条线程之间互不影响,独立存储,属于'线程私有'内存. 2.java虚拟机栈:描述的是JAVA方法执行的内存模型:每个方法执行的时候都会创建一个栈帧用于存储局部变量表.操作数栈.动态链接.方法出口等信息.每个方法的被调用直至执行完成的过程,就对应着一个栈帧在虚拟机中从入栈到出栈的过程.所以也是线程私有的. 3.本

Java 内存模型及GC原理

转至:http://blog.csdn.net/ithomer/article/details/6252552 一个优秀Java程序员,必须了解Java内存模型.GC工作原理,以及如何优化GC的性能.与GC进行有限的交互,有一些应用程序对性能要求较高,例如嵌入式系统.实时系统等,只有全面提升内存的管理效率,才能提高整个应用程序的性能. 本文将从JVM内存模型.GC工作原理,以及GC的几个关键问题进行探讨,从GC角度提高Java程序的性能. 一.Java内存模型 按照官方的说法:Java 虚拟机具

深入java虚拟机阅读笔记(jvm内存原理、异常处理部分)

深入理解Java虚拟机:JVM高级特性与最佳实践 阅读笔记(内存原理.异常处理): 1.     Jvm运行时,内存划分如图所示: 2.     程序计数器: Jvm将这个计数看作当前线程执行某条字节码的行数,会根据计数器的值来选取需要执行的操作语句.这个属于线程私有,不可共享,如果共享会导致计数混乱,无法准确的执行当前线程需要执行的语句. 该区域不会出现任何OutOfMemoryError的情况. 3.     虚拟机栈 经常说到的栈内存就是指虚拟机栈.Java中每一个方法从调用直至执行完成的

Java 详解 JVM 工作原理和流程

作为一名Java使用者,掌握JVM的体系结构也是必须的.说起Java,人们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成:Java编程语言.Java类文件格式.Java虚拟机和Java应用程序接口(JavaAPI).它们的关系如下图所示: 运行期环境代表着Java平台,开发人员编写Java代码(.java文件),然后将之编译成字节码(.class文件),再然后字节码被装入内存,一旦字节码进入虚拟机,它就会被解释器解释执行,或者是被即时代码发生器有选择的转换成机器码执

JVM GC算法 垃圾回收器

JVM的垃圾回收算法有三种: 1.标记-清除(mark-sweep):啥都不说,直接上图 2.标记-整理(mark-compact) 3.复制(copy) 分代收集算法                                                    目前的垃圾回收都采用分代收集算法.也就衍生了很多垃圾收集器 "分代收集"(Generational Collection)算法,把Java堆分为新生代和老年代,这样就可以根据各个年代的特点采用最适当的收集算法. 在新生