大战Java虚拟机【1】—— 内存
前言
要了解Java虚拟机首先要知道的基础就是内存。虚拟机存在的意义就是对内存进行管理,因为不用人为的去管理每个对象的内存,所以才让java使用起来那么方便,不用像c、c++那样去free。
运行时数据区
Java所管理的内存划分为不同的区域,每个区域都有自己的用处。
1、程序计数器PC
如果你学过汇编的话就很好理解,在计算机中指令是一条条执行的,PC就是记住当前执行到哪一行了。需要注意的是,每条线程都需要一个独立的PC,且互相之间不影响。
2、虚拟机栈
栈是一个在程序设计的时候很常见的一个数据结构,有一定计算机基础的话,你知道递归的实现其实就是利用栈,也知道递归的深度过大会导致栈溢出。而在Java虚拟机中栈是描述Java方法执行的内存模型,每个方法的执行就是虚拟机中一个入栈出栈的过程。
3、本地方法栈
这个栈和虚拟机栈一样,只是这个栈是一个VIP,只有native方法才会使用到这个栈,那什么是native方法呢?java方法可能会调用到非java-code的方法,如c的方法,这样的方法称为native方法。
4、堆
堆是最重要的一块也是比较复杂的一块区域,因为几乎所有的对象实例都在堆里分配内存。堆是垃圾回收的主要区域,因为很多用过之后没有用的对象都在这里了,它们所占用的内存都需要被回收。
5、方法区
用于存储已经被虚拟机加载的类信息、常量、静态变量等。看到它的功能基本可以想象到,它存放的东西基本上都属于那种不可改变而且一直存在的量,所以这个区域有时被称为“永久代”但是记住它们不一定都是永久的,这个区域也会被回收,只是相对来说没有像堆那样。
对象创建
内存是用来存放对象的,那么java是如何创建一个对象的呢?首先我们知道创建一个对象就是new出来,虚拟机在new之前还要做的事情是确定这个类是否已经被正确加载了。
接下来就是去分配内存了,当类被加载完成之后,我们就知道这个对象需要多大的内存了。如果内存是完整的,那就像切蛋糕一样切出一块来,如果内存是分散的,那就需要找一块足够大的切了。而内存是分散的还是完整的取决于垃圾回收的算法。
然后设置对象的参数,如这个对象是哪个类的实例,哈希码,GC分代年龄等。
最后再执行对象的init方法给每个需要的字段进行赋值,然后根据这个对象的构造方法进行初始化。
对象的访问
那么我们创建了一个对象之后,我们如何访问这个对象呢?这个时候就用到了我们的栈了,栈记录了一个对象的引用reference。这里有两种方式,第一种是这个引用数据保存了句柄数据然后堆中有一个句柄池其中记录了对象实例数据的指针,我们通过引用找到句柄池中的位置,再通过指针找到对象。第二种是指针访问,也就是直接储存了对象的地址。句柄的好处是,对象移动时reference不用改变,指针的好处是速度快。
感受虚拟机
我们运行两个程序来直观感受一下虚拟机到底做了什么事情
首先运行下面这个程序
import java.util.ArrayList;
import java.util.List; /**
* @author LinkinStar
*/
public class T {
static class A {
} public static List<A> list = new ArrayList<>(); public static void main(String[] args) {
while (true) {
list.add(new A());
}
}
}
需要注意的是,需要调整一下虚拟机的参数
Xms是JVM初始分配的堆内存
Xms是JVM最大允许分配的堆内存
然后运行就能看见异常Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
然后在相同的条件下我们运行第二个程序
/**
* @author LinkinStar
*/
public class T {
static class A {
} public static void main(String[] args) {
while (true) {
new A();
}
}
}
你会发现没有什么异常,然后你需要做的是,对比两个程序,看看这两个程序有什么不一样,这样的不一样为什么会导致这样的结果。理解了,你就知道java虚拟机到底在做什么事情了。
上面的测试是模拟了堆溢出的情况,还有方法区溢出,常量池溢出,栈溢出等,出现StackOverflowError或者OutOfMemoryError。
我们所要知道的是出现这样错误是什么样的原因导致的,以上就是在内存方向上虚拟机相关。
大战Java虚拟机【1】—— 内存的更多相关文章
- 如何写出让java虚拟机发生内存溢出异常OutOfMemoryError的代码
程序小白在写代码的过程中,经常会不经意间写出发生内存溢出异常的代码.很多时候这类异常如何产生的都傻傻弄不清楚,如果能故意写出让jvm发生内存溢出的代码,有时候看来也并非一件容易的事.最近通过学习< ...
- 深入理解java虚拟机【内存溢出实例】
通过简单的小例子程序,演示java虚拟机各部分内存溢出情况: (1).java堆溢出: Java堆用于存储实例对象,只要不断创建对象,并且保证GC Roots到对象之间有引用的可达,避免垃圾收集器回收 ...
- 从Java虚拟机的内存区域、垃圾收集器及内存分配原则谈Java的内存回收机制
一.引言: 在Java中我们只需要轻轻地new一下,就可以为实例化一个类,并分配对应的内存空间,而后似乎我们也可以不用去管它,Java自带垃圾回收器,到了对象死亡的时候垃圾回收器就会将死亡对象的内存回 ...
- Java虚拟机:内存模型详解
版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! 我们都知道,当虚拟机执行Java代码的时候,首先要把字节码文件加载到内存,那么这些类的信息都存放在内存中的哪个区域呢?当我们创建一个对象实 ...
- 初识:java虚拟机的内存划分
什么是内存? 内存是计算机中的重要原件,临时存储区域,作用是运行程序.我们编写的程序是存放在硬盘中的,在硬盘中的程序是不会运行的,必须放进内存中才能运行,运行完毕后会清空内存.Java虚拟机要运行程序 ...
- java虚拟机的内存模型
一.为什么要了解java虚拟机的内存模型 java虚拟机作为java代码运行的平台,是java技术的基石.了解java虚拟机的内存模型也就变得十分必要.它能帮助我们更好的了解java代码的运行机制,更 ...
- java虚拟机的内存机制
我们都知道,java程序的跨平台性离不开java虚拟机,虚拟机隔绝了底层操作系统,使得java程序可以直接运行在虚拟机之上.所以,对java的学习,离不开对java虚拟机的学习与了解.下面简单整理下j ...
- Java虚拟机的内存管理
众所周知,Java程序员写的代码是没有办法控制Java对象的内存释放的,完全有JVM暗箱操作. 虽然程序员把内存的释放的任务都交给了Java虚拟机,但是并不代表Java程序就不存在内存泄漏. 反而,某 ...
- 1 - JVM随笔分类(java虚拟机的内存区域分配(一个不断记录和推翻以及再记录的一个过程))
java虚拟机的内存区域分配 在JVM运行时,类加载器ClassLoader在加载到类的字节码后,交由jvm的执行引擎处理, 执行过程中需要空间来存储数据(类似于Cpu及主存),此时的这段空间的分 ...
- JAVA虚拟机:内存各个区介绍
概述:java应用程序由java虚拟机自动管理程序执行期间内存管理. 优势:1.不再需要程序员去为使用的内存在程序中手动编写释放内存代码. 2.由虚拟机管理内存不容易出现内存泄漏和内存溢出的问题. 缺 ...
随机推荐
- sqlzoo:5
展示世界的總人口. SELECT sum(population) FROM world 列出所有的洲份, 每個只有一次. select distinct(continent) from world 找 ...
- c# Winform Invoke 的用法
在Winform中线程更新UI线程 例如:Form中有一个DataGridView,我们使用Thread查询后,更新这个表格,如果在Thread中直接更新会报错. Thread th = new Th ...
- org.hibernate.hql.internal.ast.QuerySyntaxException: XXX is not mapped
异常情况: 最近在把一个项目拆分多个 module 的时候数据库查询遇到这个异常:org.hibernate.hql.internal.ast.QuerySyntaxException: Identi ...
- vue+element-ui之tree树形控件有关子节点和父节点之间的各种选中关系详解
做后端管理系统,永远是最蛋疼.最复杂也最欠揍的事情,也永远是前端开发人员最苦逼.最无奈也最尿性的时刻.蛋疼的是需求变幻无穷,如同二师兄的三十六般变化:复杂的是开发难度寸步难行,如同蜀道难,难于上青天: ...
- vue将指定区域的表格数据或element-ui中el-table的数据单笔或多笔批量导出excel
公司在后台管理系统开发中用到了 vue+element-ui 组合的框架,但随着需求的越来越复杂,前端的工作难度也呈几何倍数递增,工作量随之增大.这不,在项目中增加一个将列表数据导出为excel的需求 ...
- 浅谈C++ STL
C++ STL(标准模板库)是一套功能强大的 C++ 模板类,提供了通用的模板类和函数,这些模板类和函数可以实现多种流行和常用的算法和数据结构,如向量.链表.队列.栈. C++ 标准模板库的核心包括以 ...
- TP框架下载功能
namespace Home\Controller; use Think\Controller; use Org\Net\Http; class IndexController extends Con ...
- 反调试——jmp到那个地址
目录 1.前言 2.原理讲解 3.代码实现 前言 这节的反调试是通过构造代码来干扰正常的分析.反调试参考CrypMic勒索病毒 原理讲解 在逆向分析汇编代码时,一般都是通过汇编指令call或jmp跳到 ...
- json-server假数据
1.安装命令(全局安装) npm install json-server -g 2,检查json-server是否安装成功: json-server -h,出现如下图表示安装成功 3.安装成功后,就可 ...
- SQL笛卡尔积查询与关联查询性能对比
首先声明一下,sql会用略懂,不是专家,以下内容均为工作经验,聊以抒情. 今天帮忙验证同事发布的端口时,查看了一下相关sql内容,发现其使用的sql语句会导致笛卡尔积现象,为了帮其讲解进行了如下分析: ...