深入了解Java虚拟机和内存管理
1.java程序的执行过程
java源文件->解析器->class文件->java类加载器->java运行时数据区->执行引擎

2.我们接下来看一下java运行时数据区
包含程序计数器,虚拟机栈,本地方法栈,方法区,堆,其中程序计数器,虚拟机栈,本地方法区属于指令,方法区和堆属于数据。
一、程序计数器
用来指示程序执行哪一条指令,这跟汇编语言的程序计数器的功能在逻辑上是一样的。JVM规范中规定,如果线程执行的是非native方法,则程序计数器指向的是当前线程正在执行的字节码指令的地址和行号,如果线程执行的是native方法,则程序计数器中的值undefined。每个线程都有自己独立的程序计数器。为什么呢?因为多线程下,一个CPU内核同一时间只会执行一条线程中的指令,因此为了使每个线程在线程切换之后能够恢复到切换之前的程序执行的位置,所以每个线程都有自己独立的程序计数器。
二、Java虚拟机栈(VM Stack)
java虚拟机栈中存放的是一个个栈帧,栈是一种数据结构,数据结构是用来存放数据的,所以虚拟机栈也是用来存放数据的。存储当前线程运行方法是所需要的 数据,指令和返回地址。当程序执行一个方法时,就会创建一个栈帧并压入栈中,执行完毕,则会从栈帧中移除栈。虚拟机栈中有:局部变量表,操作数栈,动态链接,方法出口。
局部变量表:
存放局部变量的表,java的基本的数据类型(boolean、byte、char、short、int、float、long、double),对象的引用(reference类型,它不等同于对象本身,可能是一个指向对象起始地址的引用指针,也可能是指向一个代表对象的句柄或其他与此对象相关的位置)和returnAddress类型(指向了一条字节码指令的地址),其中64位长度的long和double类型的数据会占用2个局部变量空间(Slot),其余的数据类型只占用1个。局部变量表的大小在编译器就可以确定其大小了,因此在程序执行期间局部变量表的大小是不会改变的。在Java虚拟机规范中,对这个区域规定了两种异常状况:如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;如果虚拟机栈可以动态扩展(当前大部分的Java虚拟机都可动态扩展,只不过Java虚拟机规范中也允许固定长度的虚拟机栈),如果扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常。
操作数栈:
虚拟机把操作数栈作为它的工作区,程序中的所有计算过程都是在借助于操作数栈来完成的,大多数指令都要从这里弹出数据,执行运算,然后把结果压回操作数栈。
JVM将内存划分为6个部分:PC寄存器(也叫程序计数器)、虚拟机栈、堆、方法区、运行时常量池、本地方法栈

PC寄存器(程序计数器):用于记录当前线程运行时的位置,每一个线程都有一个独立的程序计数器,线程的阻塞、恢复、挂起等一系列操作都需要程序计数器的参与,因此必须是线程私有的。
java 虚拟机栈:在创建线程时创建的,用来存储栈帧,因此也是线程私有的。java程序中的方法在执行时,会创建一个栈帧,用于存储方法运行时的临时数据和中间结果,包括局部变量表、操作数栈、动态链接、方法出口等信息。这些栈帧就存储在栈中。如果栈深度大于虚拟机允许的最大深度,则抛出StackOverflowError异常。
- 局部变量表:方法的局部变量列表,在编译时就写入了class文件
- 操作数栈:int x = 1; 就需要将 1 压入操作数栈,再将 1 赋值给变量x
java堆:java堆被所有线程共享,堆的主要作用就是存储对象。如果堆空间不够,但扩展时又不能申请到足够的内存时,则抛出OutOfMemoryError异常。

方法区:方发区被各个线程共享,用于存储静态变量、运行时常量池等信息。
- 本地方法栈:本地方法栈的主要作用就是支持native方法,比如在java中调用C/C++
六、垃圾回收机制:


(2)、可达性分析
设立若干根对象(GC Root),每个对象都是一个子节点,当一个对象找不到根时,就认为该对象不可达。

3、怎么回收?
- 标记——清除算法
- 复制算法
- 分代算法
(1)、标记——清除算法
遍历所有的GC Root,分别标记处可达的对象和不可达的对象,然后将不可达的对象回收。
缺点是:效率低、回收得到的空间不连续
(2)、复制算法
将内存分为两块,每次只使用一块。当这一块内存满了,就将还存活的对象复制到另一块上,并且严格按照内存地址排列,然后把已使用的那块内存统一回 收。
优点是:能够得到连续的内存空间
缺点是:浪费了一半内存
(3)、分代算法
在java中,把内存中的对象按生命长短分为:
- 新生代:活不了多久就go die 了,比如局部变量
- 老年代:老不死的,活的久但也会go die,比如一些生命周期长的对象
- 永久代:千年王八万年龟,不死,比如加载的class信息
- 有一点需要注意:新生代和老年代存储在java虚拟机堆上 ;永久代存储在方法区上

补充:java finalize()方法:
在被GC回收前,可以做一些操作,比如释放资源。有点像析构函数,但是一个对象只能调用一次finalize()方法。
深入了解Java虚拟机和内存管理的更多相关文章
- 深入java虚拟机学习 -- 内存管理机制
前面说过了类的加载机制,里面讲到了类的初始化中时用到了一部分内存管理的知识,这里让我们来看下Java虚拟机是如何管理内存的. 先让我们来看张图 有些文章中对线程隔离区还称之为线程独占区,其实是一个意思 ...
- Java虚拟机的内存管理
众所周知,Java程序员写的代码是没有办法控制Java对象的内存释放的,完全有JVM暗箱操作. 虽然程序员把内存的释放的任务都交给了Java虚拟机,但是并不代表Java程序就不存在内存泄漏. 反而,某 ...
- java虚拟机(一)——内存管理机制与OOM异常
一 java内存区域与内存溢出异常(OOM) 1)运行时数据区域划分 1.程序计数器(Program Conuter Register) 程序计数器是一块较小的内存空间,它是当前线程执 ...
- [深入理解Java虚拟机]<自动内存管理>
Overview 走近Java:介绍Java发展史 第二部分:自动内存管理机制 程序员把内存控制的权利交给了Java虚拟机,从而可以在编码时享受自动内存管理.但另一方面一旦出现内存泄漏和溢出等问题,就 ...
- 深入理解JAVA虚拟机 自动内存管理机制
运行时数据区域 其中右侧三个一起的部分是每个线程一份,左侧两个是所有线程共享的. 程序计数器(Program Counter Register) 英文名称叫Program Counter Regist ...
- Java虚拟机理解-内存管理
运行时数据区域 jdk 1.8之前与之后的内存模型有差异,方法区有变化(https://cloud.tencent.com/developer/article/1470519). java的内存数据区 ...
- 深入理解java虚拟机,内存管理部分
1,对象回收前会调用finalize()方法,尝试自救,只能调用一次 2,上面横向对比c++的析构函数,但是java有良好的内存管理,而且try/catch做得比较好 3,回收一个常量,1,对象的实例 ...
- Java虚拟机的内存管理----垃圾收集器
1.Serial收集器 优点,是简单而高效,单线程避免了线程交互的开销. 缺点,进行垃圾回收时需要Stop the world(暂停所有用户线程). 2.ParNew收集器 它是Serial收集器的多 ...
- Java虚拟机之内存区域
原创文章,转载请标明出处! 目录 一.背景 二.运行时内存区域概述 1.官方描述 2.中文翻译 3.内存区域简述 4.运行时数据区简图 5.运行时数据区详图 三.JVM线程 JVM数据区域与线程关系 ...
随机推荐
- git 添加管理成员
git 添加管理成员 登录git后的样子: 具体操作流程看截图和说明 : * 图中1:打开设置面板: * 图中2:打开成员面板: * 图中3:添加成员功能标签: * 图中4:添加的成员,这里会弹出 ...
- oracle12c:通过oracle客户端工具配置tns,并使用sqlldr进行批量导入数据
通过oracle客户端工具配置tns: 进入oracle配置工具“Net Configuration Assistant”-> 点击“下一步”,完成tns配置. 测试是否tns可用 命令:tns ...
- 【H5-移动端开发】外部唤起本机APP的解决方法
太长时间没来博客园,原因很简单啊--太懒了!罪过罪过~ 最近公司的APP项目开始运行,采用的是原生框架+内嵌H5页面.作为一个菜鸡前端,开始入手学习移动端的界面制作加载性能优化.由于公司开始推广软件, ...
- Logstic回归采用sigmoid函数的原因
##Logstic回归采用sigmoid函数的原因(sigmoid函数能表示二项分布概率的原因) sigmoid函数: returns text ...
- 用js来实现那些数据结构07(链表01-链表的实现)
前面讲解了数组,栈和队列.其实大家回想一下.它们有很多相似的地方.甚至栈和队列这两种数据结构在js中的实现方式也都是基于数组.无论增删的方式.遵循的原则如何,它们都是有序集合的列表.在js中,我们新建 ...
- IIS&ASP.NET 站点IP跳转到域名
前言:先到微软的 https://www.iis.net/downloads/microsoft/url-rewrite 下载URL Rewrite 目标:输入ip跳转到域名所在的网站 比如58的1 ...
- 再谈前端HTML模板技术
在web2.0之前,写jsp的时候虽然有es和JSTL,但是还是坚持jsp.后面在外包公司为了快速交货,还是用了php Smart技术. web2.0后,前端模板技术风行. 代表有如下三大类: Str ...
- 机器学习技法:10 Random Forest
Roadmap Random Forest Algorithm Out-Of-Bag Estimate Feature Selection Random Forest in Action Summar ...
- cd
从当前目录切换到目标目录 cd [目标目录] 切换到用户主目录 cd cd~ 切换到根目录 cd / 切换到上级目录 cd .. cd ../ cd ..// 切换到上级目录的父目录 ...