Java运行时内存划分与垃圾回收--以及类加载机制基础
----JVM运行时内存划分----不同的区域存储的内容不同,职责因为不同
1.方法区:被线程共享,存储被JVM加载的类的信息,常量,静态变量等
2.运行时常量池:属于方法区的一部分,存放编译时期产生的字面量和符号引用
3.Java堆区:被线程共享,主要存放new出的对象,GC主要负责的区域
4.虚拟机栈:属于线程私有,存放方法中的参数局部变量等
5.本地方法栈:线程私有,存储与本地方法相关的变量
6.PC,程序计数器线程私有,用来记录当前以及下次要执行的指令
----对象访问的方式----
1.句柄:对象的引用指向一个句柄,句柄再指向堆中对象实体/方法
2.直接指针:对象的引用直接指向对象实体,通过实体指向对象的方法
----GC垃圾回收原理相关----
涉及到垃圾回收就要确定3个问题
1.那些对象需要回收?
即判断对象是活着与否--常见的算法
* 引用计数法:计数器,简单但是对于相互引用的对象无法进行判断
* 根搜素法:现在基本使用的是这个,算法思路:通过设置一些对象为根对象,通过
引用不断的向下查询,若某个对象不存在从根对象的路径,就可能被回收。
如何定义根对象?
* 虚拟机栈中的引用对象
* 方法区中类的静态引用对象
* 常量引用对象
* 本地方法引用对象
对于特殊对象处理:在内存足够时保留,不够用的时候回收。
对于这类对象如何坚定--出现了对引用的更细的划分
* 强引用:大部分对象都是
* 软引用:对象有用但是非必须
* 弱引用:对象非必须
* 虚引用:没办法通过引用操作,只是为了在回收的时候给系统通知
2.什么时候回收?
GCroots无法找到--先标记筛选(根据是否有必要执行finalize())
若没必要则不回收,反之则将其加入一个等待被回收的队列中,等待
被回收,此期间若是有引用指向该对象,就将该对象移除该队列,反之
该对象就被将回收
3.如何进行对象的回收?--根据不同的回收算法
* 标记-清除:先标记在清除,效率低且容易产生大量的小的不连续的空间
* 复制法:将内存划分两块,标记完后,将活的对象复制到新的区域,在将
原来标记的对象清除
* 标记-整理:先标记,在清除,然后将活着的对象整理,创造出连续的区域
* 分代-收集:将堆内存划分为新生代和老年代,不同的区域采取不同的回收算法
新生代采用复制法,老年代采用的是标记-整理
注意:回收方法区:虽然垃圾不多但是也存在垃圾回收
废弃常量:依据的是否有引用指向
无用的类回收需要满足3个条件
* 所有的实例被回收
* 加载该类的ClassLoader对象被回收
* 该类的Class对象无引用指向,不可以使用反射获取类
----具体的垃圾回收器-----
不同的虚拟机厂商使用不同的垃圾回收器,存在有并行和并发的垃圾回收器
并行:垃圾回收线程在执行的时候,用户线程需要等待
并发:垃圾回收器和用户线程的执行相互交替--通过CPU的调度
----对象分配策略----
1.优先分配在堆的新生代区
2.大对象进入老年代区
3.长期存活的对象分配的老年代区(通过给对象设置年龄判断其是否长期存活)
----虚拟机执行子该过程---
1.类文件的结构
是一个二进制的字节流(无符号数+表组成)
其里面包含不同的属性表集合--这些就是该类的所有信息
2.虚拟机加载机制
虚拟机将描述类的class文件加载金内存并对其进行解析最后形成JVM可以
使用的Java类型。类加载的时机--运行时期
类加载的过程:加载-(验证-准备-解析)-初始化
* 加载:根据类名获取二进制字节流--解析成JVM识别的类型--在堆中产生一个
封装该类字节码文件的Class对象
* 验证:确定当前字节码文件的信息与虚拟机信息符合,并且不会对虚拟机
造成不安全的影响
* 准备阶段:为类变量分配内存并设置默认值
* 解析:字段解析/类静态方法解析/接口方法解析
* 初始化:进行指定的初始化
类加载器--完全类加载的工作
不同的类有不同的类加载器--用来唯一确定一个类的存在
类加载器的分类:
* 启动类加载器:属于JVM的一部分,C++实现
* 其他类加载器:利用实现Java中抽象类ClassLoader,独立于JVM
* 自定义类加载器:就是通过实现已有的抽象类/接口
双亲委派加载机制:一个类加载器收到类加载请求后将其传给其父类加载器
直到类加载器的顶层,顶层处理、交给子类处理加载请求
类加载器的层次结构
* 自定义类加载器--应用程序类加载器--扩展类加载器--启动类加载器
java.lang.reflection里面封装了类文件中字段和方法--Fields,Methods
Class-封装的是类的字节码文件
ClassLoader类--是封装的是类加载机制
3.虚拟机字节码执行引擎
运行时栈帧--其实就是某个方法在运行时候占用的虚拟机栈空间
栈帧包含:局部变量表/操作数栈/动态连接/方法的返回地址
方法在调用时候栈帧进栈,运行结束栈帧出栈
只有在栈顶的栈帧才可以被虚拟机执行引擎执行
Java运行时内存划分与垃圾回收--以及类加载机制基础的更多相关文章
- Java运行时内存划分
这篇文章可以说是摘抄自周志明的<深入理解Java虚拟机>,但是加上了自己的理解,印象可以更深些. Java虚拟机在执行Java程序的时候会把他所管理的内存划分为若干个不同的数据区域,各个区 ...
- java虚拟机学习记录(内存划分、垃圾回收、类加载等机制)
一直以来觉得虚拟机是Java最难的一部分,涉及最底层的原理,学起来难度很大,而且工作中基本上用不到这些原理,所以对这部分“敬而远之”.现如今工作五年了,从Java基础到算法.数据结构.网络.数据库.设 ...
- 理解JVM之JAVA运行时内存区域
java运行时内存区域划分为方法区,堆区,虚拟机栈区,本地方法栈,程序计数器.其中方法区跟堆区是线程共享的数据区,其他的是线程私有的数据区. 1.程序计数器 程序计数器(PC)是一块较小的内存,他是存 ...
- java运行时内存模式学习
学习java运行时内存模式: 各区介绍: 方法区(线程共享):用于存放被虚拟机加载的类的元数据:静态变量,常量,以及编译和的代码(字节码),也称为永久代(所有该类的实例被回收,或者此类classLoa ...
- JVM发展史和Java运行时内存区域
目前三大主流JVM: Sun HotSpot:Sun于1997年收购Longview Technologies公司所得.Sun于2009年被Oracle收购. BEA JRockit:BEA于2002 ...
- Java程序运行时内存划分
1.Java程序跨平台运行的原因 主要原因是:各种平台的JVM和字节码文件 Java源程序--具体平台的机器代码文件---被编译器翻译成平台无关的Class文件,又用特定JVM运行字节码文件,JVM在 ...
- Java运行时内存
对于java程序员来说,并不必显示地对内存进行管理,一切都交给java虚拟机去做吧,而且,你也不一定做得比java虚拟机来得专业.好像所有内存管理都交给虚拟机去做就万事大吉了,但是,事实有时并非如此, ...
- Java进阶之内存管理与垃圾回收
Java是在JVM所虚拟出的内存环境中运行的.内存分为栈(stack)和堆(heap)两部分.我们将分别考察这两个区域. 栈 在Java中,JVM中的栈记录了线程的方法调用.每个线程拥有一个栈.在某个 ...
- Java虚拟机运行时数据区域及垃圾回收算法
程序计数器 记录正在执行的虚拟机字节码指令的地址(如果正在执行的是本地方法则为空). Java 虚拟机栈 每个 Java 方法在执行的同时会创建一个栈帧用于存储局部变量表.操作数栈.动态链接.方法出口 ...
随机推荐
- 201521123070 《JAVA程序设计》第13周学习总结
1. 本章学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 书面作业 Q1. 网络基础 1.1 比较ping www.baidu.com与ping cec.jm ...
- JavaScript自动化构建工具入门----grunt、gulp、webpack
蛮荒时代的程序员: 做项目的时候,会有大量的js 大量的css 需要合并压缩,大量时间需要用到合并压缩 在前端开发中会出现很多重复性无意义的劳动 自动化时代的程序员: 希望一切都可以自动完成 ...
- Day-1:初识开发板与基础知识
买的这款51,ARM,AVR三合一的单片机,也不知道后面具体使用会不会有问题,先玩玩看吧. ------------------------------------------------------ ...
- 开天辟地-用visualstudio2010编写helloworld
安装好visual之后,创建新项目 向源文件添加helloworld.cpp 编写helloworld代码,编译运行即可 在运行时候出现一个错误,错误和解决方法如下:
- 你的专属定制——JQuery自定义插件
前 言 絮叨絮叨 jQuery是一个快速.简洁的JavaScript框架,是继Prototype之后又一个优秀的JavaScript代码库(或JavaScript框架).jQuery设计的宗 ...
- MySQL_日期函数汇总
如果转载,请注明博文来源: www.cnblogs.com/xinysu/ ,版权归 博客园 苏家小萝卜 所有.望各位支持! 关于MySQL日期时间函数,每回总 ...
- 浅析Spring MVC工作机制
1.如何使用Spring MVC? 在web.xml中配置一个DispatcherServlet DispatchServlet初始化的时候会去寻找一个在应用程序的WEB-INF目录下的配置文件,命名 ...
- HTTP库Axios
前面的话 本文将详细介绍HTTP库Axios 概述 Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中 [安装] 在Vue中使用,最好安装两个模块axios ...
- 记一次Linux下JavaWeb环境的搭建
今天重装了腾讯云VPS的系统,那么几乎所有运行环境都要重新部署了.过程不难懂,但是也比较繁琐,这次就写下来,方便他人也方便自己日后参考参考. 我采用的是JDK+Tomcat的形式来进行JavaWeb初 ...
- 【Spring】面向切面之AOP
前言 前面已经讲解了bean的装配技术,接着学习Spring中另外一个核心概念:切面. 面向切面 面向切面编程 切面能够帮助模块化横切关注点,横切关注点可以被描述为影响应用的功能,如为业务添加安全和事 ...