JVM学习记录1--JVM内存布局
先上个图
这是根据《Java虚拟机规范(第二版)》所画的jvm内存模型。
程序计数器:程序计数器是用来记录当前线程方法执行顺序的,对应的就是我们编程中一行行代码的执行顺序,如分支,跳转,循环,异常处理等。所以在多线程下,程序计数器必然是线程隔离的,每个线程都有自己独立的程序计数器。注意,Java虚拟机中的程序计数器指向正在执行的字节码地址。
本地方法栈:本地方法栈时用来保存本地方法,即jvm调用外部的方法,比如操作系统本身的方法,或者自定义的c方法,这类方法都带有native关键字。这类又被成为java native interface。
虚拟机栈:也就是我们常说的栈,虚拟机栈时线程私有的,当虚拟机执行到一个方法时,就会在当前线程所在的栈中创建一个栈帧,栈帧用于存储局部变量、操作栈、动态链接、方法出口等信息。因此我们在方法中定义的一些基本变量,和引用变量都会存在栈中。
堆:堆是jvm内存区域最大的区域,堆被所有线程共享,几乎所有的实例对象都保存在堆中,所以堆也是垃圾收集器管理的主要区域,细分下堆还分为 eden区域,from survivor区域,to survivor区域。这个比较复杂,之后在详细说明。
方法区:又称 永久代,和堆类似,用于存放对象实例、以及class类信息、常量、静态变量、以及及时编译后的代码信息。这个区域也是所有线程共享的,也会有垃圾回收。实际上方法区只是一种概念,方法区本身也是堆的一部分,换句话说,方法区是在堆里面的,这也是人们常把jvm简单分为堆和栈的原因。但是在java8中,已经把永久代改为了元数据区(metaspace),元数据区使用的是本地内存(操作系统的内存),主要存储的类的元数据(class信息,代码信息等)。而常量,静态变量依然存在堆中。如下图
常量池:常量池是方法区的一部分,储存着常用,比如加了final关键字,或者字符串。占用的是堆中的一部分。因此以下代码也会报OOM
int i=0;
while(true){
new String(i++).intern();
}
本文借鉴
深入理解Java虚拟机-----周志明著
终于总结好了---
最新文章
- win10调用局域网内xp系统上的打印机
- Andrion错误解决:cannot be resolved or is not a field
- windows下为mysql添加日志
- easyui js基础
- Make it run, make it right, make it fast
- [HTML]网页开发学习笔记
- Android工具包
- JAX-RS 2.0 REST客户端编程实例
- jav利用反射修改类的静态变量
- Phonegap 版本minSdkVersion为8的时候的自动更新与升级
- Hibernate对象的状态和映射
- hdu 5637 Transform 最短路
- 交换两个变量的值,不借助第三个变量的 三种方法(JS实现)
- C# 使用AngleSharp 爬虫图片
- 【题解二连发】Construct Binary Tree from Inorder and Postorder Traversal &; Construct Binary Tree from Preorder and Inorder Traversal
- UserNotifications ios10 通知使用
- [RequireComponent(typeof(....))]
- Vue.js之生命周期
- 优化中的subgradient方法
- LSI SAS3008 RAID配置方法