zoukankan      html  css  js  c++  java
  • 深入理解java虚拟机学习笔记1.

    工作2年,对这块,不曾了解,惭愧惭愧,后来在别人的推荐下、,买来看了看,感觉还不错。

    记录下笔记吧。看了下书,在自己理解的程度下,将书上的例子,弄过来了。供以后没事的时候,再看。

    如果不对,还麻烦各位同行指出来,不胜感激。

    今天看的,是第二章java内存区域与内存溢出异常,自己用word模仿画了个图。

    各数据区域功能(重要,后面的例子会讲到。s):

    数据区域图中,除了方法区和堆区是线程共享区外,其他三个是线程隔离的数据区(private)

    程序计数器(Program Counter Register):属于线程私有的,占用的内存空间较少,可以看成是当前线程所执行字节码的行号指示器,字节码解释器工作时就是通过改变这个计数器的值来选择下一条,需要执行的字节码指令,分支,循环,跳转,异常处理,线程恢复等基础功能需要依赖这个计数器来完成,这个区域是jvm规范中没有规定任何OutOfMemoryError情况区域

    (Heap):jvm中内存占用最大的一块,是所有线程共享的一块内存区域.jvm启动时创建,存放的是所有对象实例(或数组),所有的对象实例都在这里进行动态分配,当类空间无法再扩张会抛出OutOfMemoryError异常

    方法区(Method Area):与堆类似,也是各个线程共享的内存区域,主要用途,用来存储已被虚拟机加载的类信息,常量,静态变量,即时编译器编译后的代码等数据,当方法区无法满足内存分配时,也抛出OutOfMemoryError异常

     

    虚拟机栈:和程序计数器一样,都属于线程私有,生命周期与线程相同,描述的是java方法执行的内存模型,每个方法执行都会创建一个栈帧,用于存储局部变量表,操作栈,动态链接,方法出口等信息,每一个方法被调用直至执行完成的过程,就对应一个栈帧在jvm stack 从入栈到出栈的过程.局部变量表存放了编译期可知的各种数据基本类型(Boolean,byte,char,short,int,float,long,double),以及对象的引用。这个区域中定义了2种异常情况,如果线程请求的栈深度大于jvm所允许的深度,将抛出StackOverflowError异常,如果jvm可以动态扩张,当扩张无法申请到足够的内存空间是会抛出OutOfMemoryError异常。(这些数据区域异常将在下面的例子都讲到)。

    本地方法栈:与虚拟机栈比较相似。不再描述。

    上面的写的太理论化,不形象,看下这个例子就明白了。

    Java栈,java堆,java方法区,三者有何关系?请看如下代码

    Object object = new Object();

    Object object 这部分存储在java栈的本地变量表中,作为一个引用(reference)类型存在

    new Object() 这部分存储在java堆中,形成了一块存储了Object类型所有的实例数据值的结构化内存,动态变化,长度不固定。

    方法区:在java堆中,必须要找到此对象类型数据,比如,对象类型,基类,实现的接口,方法等(可不可以理解成对象的所有数据结构都存在这里?)都存放在方法区

    2.关于OutOfMemoryError异常的几个例子:

    Ajava堆溢出:

    上面讲过,java堆是用来存储对象实例的,只要不停创建对象, gc来不及回收,为了体现效果,在eclipse jvm args 设置了最少120M和最大1024M的内存占用参数。

     1 import java.util.ArrayList;
    2 import java.util.List;
    3
    4 public class TestHeapOOM {
    5 /**
    6 * vm args -Xmn120M -Xmx1024M
    7 */
    8 public static void main(String[] args) {
    9 List<String> list = new ArrayList<String>();
    10 while(true){
    11 list.add("sss");
    12 }
    13 }
    14 }

      

    运行结果:

    Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

        at java.util.Arrays.copyOf(Unknown Source)

    总结:java OutOfMemoryError异常,如果出现内存溢出,除了有java.lang.OutOfMemoryError,后面来还有java heap space提示信息。

    当然,堆还有一种内存泄露,与内存溢出不同的是,这可能会是垃圾收集器无法自动回收造成的,这种情况要通过分析工具,具体分析才能定位。

    2.jvm栈和本地方法栈的溢出

    看这个前,请重新看下各数据区域功能jvm栈和本地方法栈的描述。

    看完描述,结合代码来说明。

    AStackOverflowError例子,需要设置的参数-Xss

    /**
    * jvm args -Xss10M
    */
    public class TestStackSOF {

    public long stackLenth = 1;

    public void stackSOF(){
    stackLenth
    ++;
    stackSOF();
    }
    public static void main(String[] args) {
    TestStackSOF tss
    = new TestStackSOF();
    try{
    tss.stackSOF();
    }
    catch(Throwable e){
    System.out.println(
    "stackLenth: "+tss.stackLenth);
    try {
    throw e;
    }
    catch (Throwable e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
    }
    }
    }
    }

      

    执行的结果:

    stackLenth: 326323

    java.lang.StackOverflowError

        at com.cn.TestStackSOF.stackSOF(TestStackSOF.java:9)

        at com.cn.TestStackSOF.stackSOF(TestStackSOF.java:9)

    如果把-Xss调到50M,执行的结果是:

    stackLenth: 1637043

    java.lang.StackOverflowError

        at com.cn.TestStackSOF.stackSOF(TestStackSOF.java:9)

        at com.cn.TestStackSOF.stackSOF(TestStackSOF.java:9)

    总结:不难看出,-Xss大小不一样,执行的结果也不一样。如果以后在项目中遇到

    java.lang.StackOverflowError异常,可以先检查代码是否有无限递归,如果不是,

    可加大-Xss大小再看运行效果

    方法区溢出:解题用动态代理产生大量的类,jvm args设置的参数

    –XXPermSize=10M –XX:MaxPermSize=10M

    (代码,有时间再补上。)

     

  • 相关阅读:
    一个漂亮的PHP验证码
    一个漂亮的php验证码类(分享)
    PHP中exit()与die()的区别
    自定义PHP页面跳转函数redirect($url, $time = 0, $msg = '')
    MySQL时间字段究竟使用INT还是DateTime
    mysql中为int设置长度究竟是什么意思
    Array数组对象
    Math对象
    对象篇学习-字符串对象
    事件的学习
  • 原文地址:https://www.cnblogs.com/montya/p/2174110.html
Copyright © 2011-2022 走看看