JVM 内存分析
简述JVM垃圾回收机制
- 垃圾回收机制时Java提供的自动释放内存空间的机制.
- 垃圾回收机制时JVM自导的一个线程,用于回收没有被引用的对象.
JVM有一个运行时的数据区来管理内存.其主要包括五大部分:程序计数器,虚拟机栈,本地方法栈,方法区,堆.
其中程序计数器,虚拟机栈,本地方法栈 每个线程私有的内存空间,和线程的生命周期相同.如栈中每个栈帧分配多少的内存基本上在类结构确定时就以几个确定了.无需考虑内存回收的问题.
方法区和堆就和上面不一样了,一个接口的多个类实现需要的内存可能不一样,只有在程序运行期才指导会创建哪些对象,这部分内存的分配和回收都是动态的, GC主要关注的就是该部分内存.
Java虚拟机数据区域

黄色: 由所有线程共享的数据区.
绿色: 线程隔离的数据区.
- 程序计数器:当前线程所执行的字节码的行号指示器,在虚拟机的概念模式里,字节码解释器工作就是通过改变程序计数器的值来选择下一跳需要执行的字节码指令,分支,循环,跳转,异常处理,线程回复等基础功能都要依赖这个基础器来完成.
Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,指挥执行一条线程中的指令.因此,为了线程切换之后能够恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线成之间的计数器互不影响,独立存储.
如果线程正在执行一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址,如果正在执行的是Native方法,则这个计数器值为空,此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域.
- Java虚拟机栈:其也是线程私有的,生命周期和线程相同.其永固Java方法执行的内存模型:每个方法在执行的时候都会创建一个栈帧用于存取局部变量表,操作数栈,动态链接,方法出口等信息.
3.本地方法栈:其也是线程私有,描述的是Native方法执行的内存模型.虚拟机规范对本地方法栈中方法所使用的语言,使用方式和数据结构并没有强制规定.
- Java堆:线程共享,所有的对象实例和数组都要在堆上分配内存.Java堆是垃圾手机管理的主要区域,由于现在收集器基本采用分代回收算法,所以Java堆还可以细分为:新生代和老年代.从内存分配的角度上看,线程共享的Java堆中可能划分出多个线程私有的分配缓冲区.如果队中没有内存完成实力分配,并且堆无法完成扩展,将会抛出OutOfMemoryError的错误.
- 方法区:线程共享,存储虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据.此处的垃圾回收主要针对,常量池的回收和对类型的加载.
运行时常量池:方法区的一部分,它用于存放编译器生成的各种字面量和符号引用.
- 直接内存:直接内存不是虚拟机运行时数据区的一部分,在NIO类中引入一种基于通道与缓冲区的IO方式,它可以使用Native函数库直接分配堆外内存,然后通过一个存储在Java对中的DirectByteBuffer对象作为这块内存的引用进行操作.
对象的创建
- 之前没有加载过的情况下
- 类加载,同时初始化类中的静态的属性和方法.(所有带static修饰符的属性,方法和静态代码块都放在内存中的方法区,而非静态属性放在堆区.)
- 执行静态代码块(主动执行. 此时静态方法已经在方法区中,就算不实例化对象也可以直接用类区调用静态方法了, 而在此之后才开始初始化的属性和方法是不可以在其中被调用执行的(例如非静态方法和属性).)
- 分配内存空间(此时是开始new 对象了.在堆中开始开辟大小足够的空间,然后将地址赋予占内存中以便引用.放在堆内存中的时候,各种属性赋予默认值(0和null).).
- 调用父类构造器
- 自己的声明属性有显示赋值则开始将,显示赋值覆盖默认赋值.
public class test { //1.第一步,准备加载类
public static void main(String[] args) {
new test(); //4.第四步,new一个类,但在new之前要处理匿名代码块
}
static int num = 4; //2.第二步,静态变量和静态代码块的加载顺序由编写先后决定
{
num += 3;
System.out.println("b"); //5.第五步,按照顺序加载匿名代码块,代码块中有打印
}
int a = 5; //6.第六步,按照顺序加载变量
{ // 成员变量第三个
System.out.println("c"); //7.第七步,按照顺序打印c
}
test() { // 类的构造函数,第四个加载
System.out.println("d"); //8.第八步,最后加载构造函数,完成对象的建立
}
static { // 3.第三步,静态块,然后执行静态代码块,因为有输出,故打印a
System.out.println("a");
}
static void run() // 静态方法,调用的时候才加载// 注意看,e没有加载
{
System.out.println("e");
}
}
无用类的判定:
- 该类的所有实例都已经被回收,也就是堆中不存在该类的任何实例.
- 类加载器已经被回收.
- 该类对应的对象没有在任何地方被引用,也就是说这东西你再也没办法用了.
JVM 内存分析的更多相关文章
- 大数据学习--day13(字符串String--源码分析--JVM内存分析)
字符串String--源码分析--JVM内存分析 String 类的对象 , 是不可变的字符串对象呢 这个不可变很重要,之后要讲的intern()也离不开它的不可变性. https://www.cnb ...
- 学习记录--JVM内存分析
今天刷牛客网的题时,看到了两位大神关于JVM内存分析的讲解,就顺手记录学习一下. JVM内存模型图 方法区域存放了所加载的类的信息(名称.修饰符等).类中的静态变量.类中定义为final类型的常量.类 ...
- Day05_22_实例化对象的JVM内存分析
创建对象的 JVM 内存分析 *new 运算符的作用是创建对象,在JVM堆内存中开辟新的内存空间 *方法区内存:在类加载的时候,class字节码文件被加载到该内存空间当中 *栈内存(局部变量):方法代 ...
- 利用MAT玩转JVM内存分析(一)
本文首发于公众号:javaadu 尽管JVM提供了自动内存管理的机制,试图降低程序员的开发门槛,确实也实现了这一目标,在日常开发中,我们一般都不需要关心对象的内存释放.JVM大部分都是使用trace算 ...
- 说下Java堆空间结构,及常用的jvm内存分析命令和工具
Java堆空间结构图:http://www.cnblogs.com/SaraMoring/p/5713732.html JVM内存状况查看方法和分析工具: http://blog.csdn.net/n ...
- JVM内存分析
1.java内存模型分析 java虚拟机运行时数据存储区域包括线程隔离和线程共享两类,整个PC的内存图如下所示: 下面对以上内存区域说明: 1.1 register和cache 当代计算机一般有多个c ...
- JVM堆空间结构及常用的jvm内存分析命令和工具
jdk8之前的运行时数据区域 程序计数器 是一块较小的内存空间,它可以看做是当前线程所执行的字节码的行号指示器.每个线程都有一个独立的程序计数器,这类内存区域为"线程私有",此内存 ...
- JVM内存分析工具MAT使用
1. 首先去官网下载MAT软件,路径如下: 点击打开链接 2. 将heap dump文件打开即可分析.
- 配置JVM内存 查看内存工具
一.配置JVM内存 1.配置JVM内存的參数有四个: -XmxJavaHeap最大值.默认值为物理内存的1/4.最佳设值应该视物理内存大小及计算机内其它内存开销而定. -XmsJavaHeap初始值, ...
随机推荐
- 《程序员代码面试指南》第八章 数组和矩阵问题 在数组中找到出现次数大于N/K 的数
题目 在数组中找到出现次数大于N/K 的数 java代码 package com.lizhouwei.chapter8; import java.util.ArrayList; import java ...
- HDU2296 Ring —— AC自动机 + DP
题目链接:https://vjudge.net/problem/HDU-2296 Ring Time Limit: 2000/1000 MS (Java/Others) Memory Limit ...
- static语句块的执行时间
package utfTest; public class Test01 { public static void main(String[] args) { //Person.show(); Sys ...
- .NET中Eval()方法大全
<%# Bind("Subject") %> //绑定字段<%# Container.DataItemIndex + 1%> //实现自动编号<%# ...
- [原创]Java集成PageOffice在线打开编辑word文件 - Spring Boot
开发环境:JDK1.8.Eclipse.Sping Boot + Thymeleaf框架. 一. 构建Sping Boot + Thymeleaf框架的项目(不再详述): 1. 新建一个maven p ...
- 【Lintcode】018.Subsets II
题目: Given a list of numbers that may has duplicate numbers, return all possible subsets Notice Each ...
- 单机11g ogg 双向DML复制
环境说明: Linux为Linux 2.6.32-573.el6.x86_64 Oracle为 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Pr ...
- C#如何把XSD中HexBinary类型序列化uint类型
xml schema中有hexBinary类型, 我们在实现C#的Serialization时,一般默认把hexBinary映射为byte[],但是有些情况我们需要把 hexBinary映射为uint ...
- Scala学习——array与arraybuffer的区别(初)
1.由于Array是不可变的,所以不能直接地对其元素进行删除操作,只能通过重赋值或过滤生成新的Array的方式来删除不要的元素. 而ArrayBuffer是可变的,本身提供了很多元素的操作,当然包括删 ...
- JavaScript高级程序设计学习笔记第十三章--事件
事件冒泡: IE 的事件流,事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档).例如: <!DOCTYPE html> <htm ...