一直对jvm看了又忘,忘了又看的。今天做一个笔记整理存放在这里。

我们先看一下JVM的内存模型图:

上面有5个区,这5个区干嘛用的呢?

我们想象一个场景:

我们有一个class文件,里面有很多的类的定义是不是,类的定义放在什么地方呢?类的定义就放在方法区里面。

程序在运行时会产生很多的对象,比如LinkList等这些对象就存放在堆里面。

栈:

我们的程序在运行时本质上就是启动线程在运行,比如main函数就是一个主线程。一个main主线程可以有很多的子线程。

线程在工作就是执行我们的各种方法。方法里面肯定有我们自己定义了一些局部的变量,比如我们在方法里面new了一个对象,对象肯定是放在堆里面的,但是对堆的引用我们就放在栈里面。那么栈就有问题了,我们一个程序有很多的线程,如果把所有的线程里面的变量存放在一起,肯定有会有变量是重复的,冲突。所有不能放在一起。所以栈里面是分线程来存放的。每一个线程都是自己的栈空间,线程私有的。堆是线程共享的。

栈里面有一个细节:

就是说一个栈空间是以不同的线程区分开来。每个线程有自己栈,每个线程里面又会执行很多的方法,每一个方法对应一个栈帧:

每个方法执行时都会创建一个栈帧(Stack Frame)用语存储局部变量表、操作数栈、动态链接、方法出口等信息。从下图从可以看到,每个线程在执行一个方法时,都意味着有一个栈帧在当前线程对应的栈帧中入栈和出栈。

图中可以看到每一个栈帧中都有局部变量表。局部变量表存放了编译期间的各种基本数据类型,对象引用等信息。

好了,我们看一下具体的东西:

本地方法栈(Native Stack

本地方法栈(Native Stack)与Java虚拟机站(Java Stack)所发挥的作用非常相似,他们之间的区别在于虚拟机栈为虚拟机栈执行java方法(也就是字节码)服务,而本地方法栈则为使用到Native方法服务。

 堆(Heap

对于大多数应用来说,Java Heap是Java虚拟机管理的内存的最大一块,这块区域随着虚拟机的启动而创建。在实际的运用中,我们创建的对象和数组就是存放在堆里面。如果你听说线程安全的问题,就会很明确的知道Java Heap是一块共享的区域,操作共享区域的成员就有了锁和同步。在程序的运行中不断地new 对象,就存在堆里面。

与Java Heap相关的还有Java的垃圾回收机制(GC),Java Heap是垃圾回收器管理的主要区域。程序猿所熟悉的新生代、老生代、永久代的概念就是在堆里面,现在大多数的GC基本都采用了分代收集算法。如果再细致一点,Java Heap还有Eden空间,From Survivor空间,To Survivor空间等。

Java Heap可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可。

上面这张图就是我们新生代,老年代的图。涉及到垃圾回收机制。

我们来介绍一下垃圾回收机制:

刚开始时创建的对象都存放在Eden Sapce里面(伊甸园,新生代),大家都无忧无虑的。然后呢 ,垃圾回收机制来了。先对生活在伊甸园的对象检测一次,发现还有利用价值就把对象放在Survivor空间里面的From Space,survivior空间分为两块,一块是From Space,一块是ToSapce空间。ToSpace空间是很少用的(就是用来做垃圾回收的挪动的)。然后垃圾回收机制对From Space的对象回收比如18次,还能幸存下来,就放在老年代里面(Old Generation)。我们很奇怪,这里的ToSpace是干嘛用的。

好了我们来介绍下垃圾回收算法:

有 两种算法。

1:对象A有没有引用对象B.有引用就不是垃圾,这种方法有问题。A,B相互引用,就不能区分出是不是垃圾了。

2:根节点搜索。从根节点往下搜索。能搜索到了就不是垃圾,不能搜索到的,就是垃圾。

这是由映射表记录的,再详细就不知道了。

对象其实就是一个方格:

如上,红色是好的对象,黑色的是垃圾对象。

我们怎么去回收黑色的对象呢:

方法一:标志-清除:

直接把黑色的对象清除掉。

但是有一个问题:这样清除掉的恶化,我的空间变得很零散。下次要放一个大的对象的话(必须是一个连续的空间)比如四个格子,就放不下去了。

方法二:标记整理:

我只移动有用的:把红色的有用的对象移动到白色的空白地方。但是造成的问题是:对在运行的程序有影响。

方法三:

复制算法:

预先存留一块有用的的空间:那就是上文提到的ToSpace空间。

在FromSpace空间中,垃圾回收机制把没用的的对象标记成黑色的,然后把红色的有用的对象都转移到右边的ToSpace空间,等到垃圾回收机制把左边的黑色和红色全部清除之后。再把右边的ToSpace的那些红色有用对象再移植到左边的FromSpace空间。这样就整齐了。

然后我们会想一个问题。那右边给他预留这么大的空间不是很浪费吗?其实实际上右边的空间不需要那么大,只要一点点就够了。如下图

因为我们的有用的对象(红色的方块)其实是很少的。很多对象用好一次就不用了的。

  方法区(Method Area

方法区(Method Area)与堆(Java Heap)一样,是各个线程共享的内存区域,它用于存储虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据。虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分,但是她却有一个别名叫做非堆(Non-Heap)。分析下Java虚拟机规范,之所以把方法区描述为堆的一个逻辑部分,应该觉得她们都是存储数据的角度出发的。一个存储对象数据(堆),一个存储静态信息(方法区)。

在上文中,我们看到堆中有新生代、老生代、永久代的描述。为什么我们将新生代、老生代、永久代三个概念一起说,那是因为HotSpot虚拟机的设计团队选择把GC分代收集扩展至方法区,或者说使用永久代来实现方法区而已。这样HotSpot的垃圾收集器就能想管理Java堆一样管理这部分内存。简单点说就是HotSpot虚拟机中内存模型的分代,其中新生代和老生代在堆中,永久代使用方法区实现。根据官方发布的路线图信息,现在也有放弃永久代并逐步采用Native Memory来实现方法区的规划,在JDK1.7的HotSpot中,已经把原本放在永久代的字符串常量池移出。

大数据基础篇----jvm的知识点归纳-5个区和垃圾回收机制的更多相关文章

  1. JVM运行时数据区和垃圾回收机制

    最近参考各种资料,尤其是<深入理解Java虚拟机 JVM高级特性和最佳实践>,大牛之作.把最近学习的Java虚拟机组成和垃圾回收机制总结一下. 你不会的都是新知识,学无止境,每天进步一点点 ...

  2. java基础(一):谈谈java内存管理与垃圾回收机制

    看了很多java内存管理的文章或者博客,写的要么笼统,要么划分的不正确,且很多文章都千篇一律.例如部分地方将jvm笼统的分为堆.栈.程序计数器,这么分太过于笼统,无法清晰的阐述java的内存管理模型: ...

  3. 大数据基础篇(一):联机分析处理(OLAP) 与 联机事务处理(OLTP)

    联机事务处理(OLTP) OLTP也称实时系统(Real Time System),支持事务快速响应和大并发,这类系统典型的有ATM机(Automated Teller Machine)系统.自动售票 ...

  4. JVM java垃圾回收机制

    一.jvm简介 1.JVM内存运行时数据区的三个重要的地方 1.1.堆(heap):它是最大的一块区域,用于存放对象实例数组,是全局共享的. 1.2.栈(stack):全称为虚拟机栈,主要存储基本数据 ...

  5. Java基础教程——垃圾回收机制

    垃圾回收机制 Garbage Collection,GC 垃圾回收是Java的重要功能之一. |--堆内存:垃圾回收机制只回收堆内存中对象,不回收数据库连接.IO等物理资源. |--失去使用价值,即为 ...

  6. 大数据工具篇之Hive与HBase整合完整教程

    大数据工具篇之Hive与HBase整合完整教程 一.引言 最近的一次培训,用户特意提到Hadoop环境下HDFS中存储的文件如何才能导入到HBase,关于这部分基于HBase Java API的写入方 ...

  7. Java基础篇(JVM)——类加载机制

    这是Java基础篇(JVM)的第二篇文章,紧接着上一篇字节码详解,这篇我们来详解Java的类加载机制,也就是如何把字节码代表的类信息加载进入内存中. 我们知道,不管是根据类新建对象,还是直接使用类变量 ...

  8. Java基础篇(JVM)——字节码详解

    这是Java基础篇(JVM)的第一篇文章,本来想先说说Java类加载机制的,后来想想,JVM的作用是加载编译器编译好的字节码,并解释成机器码,那么首先应该了解字节码,然后再谈加载字节码的类加载机制似乎 ...

  9. 大数据工具篇之Hive与MySQL整合完整教程

    大数据工具篇之Hive与MySQL整合完整教程 一.引言 Hive元数据存储可以放到RDBMS数据库中,本文以Hive与MySQL数据库的整合为目标,详细说明Hive与MySQL的整合方法. 二.安装 ...

随机推荐

  1. django-访问控制

    django自带的用户认证系统提供了访问控制的的功能.   1.只允许登录的用户登录   django的用户可分为两类,一是可认证的用户,也就是在django.contrib.auth.models. ...

  2. BZOJ.1497.[NOI2006]最大获利(最小割 最大权闭合子图Dinic)

    题目链接 //裸最大权闭合子图... #include<cstdio> #include<cctype> #include<algorithm> #define g ...

  3. 不让Editplus保存时java文件时生成.bak文件

    EditPlus是一个强大的编辑工具,不单单是编辑文字强大,很多的刚开始学习编程语言的初学者会选择它,例如 html,js,php,java.但是却遇到一个问题,就是每次编辑完后点保存就会出 现bak ...

  4. filter的dispatcher节点

    1.FORWARD (1)a.jsp页面内容如此<jsp:forward page="/b.jsp"></jsp:forward> (2) a.jsp页面内 ...

  5. windows + php + redis的安装

    我讲述一下我在 php 中安装 redis 的详细过程,仅供参考: 系统版本:windows7 + 64 位操作系统. php版本 : php5.6 redis版本 : redis 2.2.7 (由于 ...

  6. Python不定参数函数

    1. 元组形式 def test1(*args): print('################test1################') print(type(args)) print(arg ...

  7. Linux ./configure --prefix命令

    源码的安装一般由3个步骤组成:配置(configure).编译(make).安装(make install),具体的安装方法一般作者都会给出文档,这里主要讨论配置(configure).Configu ...

  8. UnityEditor研究学习之EditorWindow

    在unity使用过程中,其实我们都是在各个不同功能的Window下工作. 比如在Scene窗口中操作物体,在Inspector中操作物体属性,在Game视窗中观察游戏状态. 所以窗口是Unity的灵魂 ...

  9. WebMagic编译时提示Failure to transfer org.apache.maven.plugins:maven-surefire-plugin:pom:2.18的解决方法

    问题描述:    从http://git.oschina.net/flashsword20/webmagic 下载最新代码,按照http://webmagic.io/docs/zh/posts/ch3 ...

  10. 【T02】理解子网和CIDR的概念

    1.IP地址分为5类,A.B.C.D.E,它们的前缀分别是: A:0 网络个数2^7,主机个数2^24,大概1千6百万 B:10 网络个数2^14,大概1万6千,主机个数2^16,大概6万5千 C:1 ...