JVM 学习笔记(一)
JVM ----Java Virtual Machine (熟称:JAVA虚拟机),JVM 在执行JAVA程序的过程中将内容划分为若干个区域,其有各自的用途和管理机制。如下图:
1. 程序计算器(Program Counter Register) -- 是当前线程所执行字节码的行号指示器,通过改变其值来实现执行不同的代码指令。内存占用小,线程私有,支持多线程处理(多线程时,每个线程有一个独立程序计算器,已达到各自互不影响), 也正是由于这些特点,该区域是JVM规范中唯一没有规定任何OutOfMemoryError的区域。
2. JAVA 虚拟机栈(JVM Stack)
也是线程私有,和线程有相同的生命周期,是JAVA方法执行的内存模型, 即:每个方法执行时,都会同时创建一个Stack Frame(栈帧)用于存储局部变量(8种基本数据类型、对象引用类型)、操作数栈、动态链接、方法出口信息。方法调用到执行完成的过程也是Stack Frame栈帧出、入JVM Stack的过程.
在JVM规范中,规定了两种内存异常:
一是:线程请求的栈深度超过了栈允许的最大深度,将抛出:StackOverflowError 异常。
二是:当JAVA虚拟机动态扩展时,无法申请到足够的内存时,将抛出:OutOfMemoryError异常。
以下样例属于第一种情形:
/**
* VM Args: -Xss128K
* @author yql
*
*/
public class JavaVMStackSOF { private int stackLength = 1; public void stackLeak(){
stackLength ++;
stackLeak();
} public static void main(String[] arg) throws Throwable{ JavaVMStackSOF oom = new JavaVMStackSOF();
try{
oom.stackLeak();
}catch(Throwable e ){
System.out.println("Stack length:"+ oom.stackLength);
throw e;
}
}
}
运行结果:
Stack length:7907
Exception in thread "main" java.lang.StackOverflowError
at JavaVMStackSOF.stackLeak(JavaVMStackSOF.java 13)
at JavaVMStackSOF.stackLeak(JavaVMStackSOF.java 13)
at JavaVMStackSOF.stackLeak(JavaVMStackSOF.java 13)
... (省略相同栈信息)
以下属于第二种情形:(注意!!!: 在运行以下样例前,请保持所有工作,可能导致操作系统假死。)
/**
* VM Args: -Xss2M
* @author yql
*
*/
import java.lang.*;
public class JavaVMStackOOM {
private void dontStop(){
while(true){
}
}
public void stackLeakByThread(){
while(true){
Thread thread = new Thread(new Runnable(){
@Override
public void run(){
dontStop();
}
});
thread.start();
}
}
public static void main(String[] arg) throws Throwable{ JavaVMStackOOM oom = new JavaVMStackOOM();
oom.stackLeakByThread();
}
}
运行结果为:
Exception in thread "main" java.lang.OutofMemoryError: unable to create new native thread.
3. 本地方法栈(Native Method Stack)
与JVM stack 相似,JVM stack 为虚拟机执行JAVA方法服务,而Native Method Stack 是为虚拟机执行本地方法服务。有的虚拟机对两者没有区分,合二为一。
同样会存在两种异常: StackOverflowError 和 OutOfMemoryError 异常. (样例如第2点中)
4. JAVA 堆(Heap)
Heap 是java内存管理中最大的一块内存区域,被所有线程共享,用于存放对象实例,几乎所有的对象实例和数组都在此分配。
在JVM规范中规定,JAVA堆可以物理不联系,只要逻辑空间联系即可。这样,当堆Heap无法完成再扩展时,将会抛出:OutOfMemoryError异常。
所以,不断的创建对象,就会导致内存溢出.
/**
* VM Args: -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError
* @author yql
*
*/
import java.util.*;
public class HeapOOM { static class OOMObject{
} public static void main(String[] arg){ List<OOMObject> list = new ArrayList<OOMObject>(); while(true){
list.add(new OOMObject());
}
}
}
运行结果为:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Unknown Source)
at java.util.Arrays.copyOf(Unknown Source)
at java.util.ArrayList.grow(Unknown Source)
at java.util.ArrayList.ensureExplicitCapacity(Unknown Source)
at java.util.ArrayList.ensureCapacityInternal(Unknown Source)
at java.util.ArrayList.add(Unknown Source)
at HeapOOM.main(HeapOOM.java:17)
5. 方法区(Method Area)
方法区也是多线程共享的内存区域,用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译的代码数据。(JVM规范把方法区描述为堆的一个逻辑区域)
方法区在无法满足内存分配时,将抛出OutOfMemoryError 异常。
6. 运行时常量池(Runtime Constant Pool )
运行时常量池是方法区的一部分,用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后存放到方法区的运行时常量池。
/**
* VM Args: -Xss2M
* @author yql
*
*/
import java.util.*;
public class RuntimeConstantPoolOOM {
public static void main(String[] arg) throws Throwable{
//使用List 保持常量池引用, 避免Full GC回收常量行为
List<String> list = new ArrayList<String>();
long i= 0l;
while(true){
list.add(String.valueOf(i++).intern());
}
}
}
运行结果:
Exception in thread "main" java.lang.OutOfMemoryError: PermGen space
at java.lang.String.intern(Native Method)
at RuntimeConstantPoolOOM.main(RuntimeConstantPoolOOM.java 13)
....
7. 直接内存(Direct Memory)
本机内存分配不受JAVA 虚拟机(堆,栈等)的影响,但是受机器内存的影响,当各区域内存总和大于物理内存时,导致动态扩展内存出现:OutOfMemoryError异常。
对象访问
对象访问主要有两种方式:
一种是,通过句柄访问对象;(优点在于:reference 中存储的是稳定的句柄地址,在对象被移动时,只改变句柄中实例数据指针,而reference本身不变)
一种是,通过直接指针访问对象。(优点在于:速度更快,节省了一次指针定位时间)
JVM 学习笔记(一)的更多相关文章
- JVM学习笔记:虚拟机的类加载机制
JVM类加载机制分两部分来总结: (1)类加载过程 (2)类加载器 一.JVM类加载过程 类的加载过程:加载 →连接(验证 → 准备 → 解析)→ 初始化. 类的生命周期:加载 →连接(验证 → 准备 ...
- JVM学习笔记:字节码执行引擎
JVM学习笔记:字节码执行引擎 移步大神贴:http://rednaxelafx.iteye.com/blog/492667
- JVM学习笔记(四)------内存调优【转】
转自:http://blog.csdn.net/cutesource/article/details/5907418 版权声明:本文为博主原创文章,未经博主允许不得转载. 首先需要注意的是在对JVM内 ...
- JVM学习笔记(四)------内存调优
首先需要注意的是在对JVM内存调优的时候不能只看操作系统级别Java进程所占用的内存,这个数值不能准确的反应堆内存的真实占用情况,因为GC过后这个值是不会变化的,因此内存调优的时候要更多地使用JDK提 ...
- java jvm学习笔记七(jar包的代码认证和签名)
欢迎装载请说明出处:http://blog.csdn.net/yfqnihao 前言: 如果你循序渐进的看到这里,那么说明你的毅力提高了,jvm的很多东西都是比较抽像的,如果不找相对应的代码来辅助理解 ...
- java之jvm学习笔记六-十二(实践写自己的安全管理器)(jar包的代码认证和签名) (实践对jar包的代码签名) (策略文件)(策略和保护域) (访问控制器) (访问控制器的栈校验机制) (jvm基本结构)
java之jvm学习笔记六(实践写自己的安全管理器) 安全管理器SecurityManager里设计的内容实在是非常的庞大,它的核心方法就是checkPerssiom这个方法里又调用 AccessCo ...
- java之jvm学习笔记三(Class文件检验器)
java之jvm学习笔记三(Class文件检验器) 前面的学习我们知道了class文件被类装载器所装载,但是在装载class文件之前或之后,class文件实际上还需要被校验,这就是今天的学习主题,cl ...
- java之jvm学习笔记五(实践写自己的类装载器)
java之jvm学习笔记五(实践写自己的类装载器) 课程源码:http://download.csdn.net/detail/yfqnihao/4866501 前面第三和第四节我们一直在强调一句话,类 ...
- java之jvm学习笔记四(安全管理器)
java之jvm学习笔记四(安全管理器) 前面已经简述了java的安全模型的两个组成部分(类装载器,class文件校验器),接下来学习的是java安全模型的另外一个重要组成部分安全管理器. 安全管理器 ...
- java之jvm学习笔记二(类装载器的体系结构)
java的class只在需要的时候才内转载入内存,并由java虚拟机的执行引擎来执行,而执行引擎从总的来说主要的执行方式分为四种, 第一种,一次性解释代码,也就是当字节码转载到内存后,每次需要都会重新 ...
随机推荐
- Android主题换肤 无缝切换
2016年7月6日 更新:主题换肤库子项目地址:ThemeSkinning,让app集成换肤更加容易.欢迎star以及使用,提供改进意见. 更新日志: v1.3.0:增加一键切换切换字体(初版)v1. ...
- ASP.NET Mvc开发之EF延迟加载
EF延迟加载:就是使用Lamabda表达式或者Linq 从 EF实体对象中查询数据时,EF并不是直接将数据查询出来,而是在用到具体数据的时候才会加载到内存. 一,实体对象的Where方法返回一个什么对 ...
- linux下如何删除文件夹
直接rm就可以了,不过要加两个参数-rf 即:rm -rf 目录名字-r 就是向下递归,不管有多少级目录,一并删除-f 就是直接强行删除,不作任何提示的意思删除文件夹实例: rm -rf /var/l ...
- C# if,ifelse语句
1,if语句的判断是根据布尔表达式的值. if语句主要有两种方式,如下 Code(1)if(boolean) do (2)if(boolean){ do } 一般大家都是用第二种方法,因为第一种方法只 ...
- JQ实现复选框的全选反选不选
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- hibernate篇章四-- Hibernate配置文件中hiberante.hbm2ddl.auto四个参数的配置
我们在搭建环境的时候,在配置文件中有一个属性标签为: <property name="hibernate.hbm2ddl.auto"> </propert ...
- 谨以此错误警醒自己---java.lang.ClassNotFoundException:
今天在做一个小型的实例,用了面向接口编程,采用了工厂来获取数据源和实例,在从配置文件读取实例时,报了个错误如下图: 于是一个一个的类去找错误,最后也没找到,以为工厂代码出错了,看了好几次也没看出来错误 ...
- Cesium的api之关于viewer(二)
1.构建一个viewer,如下创建:options的参数根据实际情况,进行设定 var viewer = new Cesium.Viewer('cesiumContainer', { //Start ...
- Solr集群的搭建以及使用(内涵zookeeper集群的搭建指南)
1 什么是SolrCloud SolrCloud(solr 云)是Solr提供的分布式搜索方案,当你需要大规模,容错,分布式索引和检索能力时使用 SolrCloud.当一个系统的索引数据量少的时候 ...
- DAG模型——嵌套矩阵
有向无环图上的动态规划是学习动态规划的基础,很多问题都可以转化为DAG上的最长路.最短路或路径计数问题. 嵌套矩阵 有n个矩阵,每个矩阵可以用两个整数a,b描述,表示它的长和宽.矩阵X(a,b)可以嵌 ...