zoukankan      html  css  js  c++  java
  • jvm_第二章

    jvm内存分析:

    1:线程私有的虚拟机栈:每进入一个方法创建一个虚拟机栈,包括局部变量表,操作数栈,动态链接等,狭义的栈指的是局部变量表部分,局部变量表存放基本数据类型和各对象引用,这些都是编译期可知的,包括局部变量表的大小,在进入方法后创建的局部变量大小是不会改变了

    2:堆,垃圾回收的主要区域

    3:方法区:存放类的信息包括class对象,静态变量,常量等,运行时常量池也是方法区的一部分,Class文件的常量池存放着便衣生成的各种字面量和符号引用,这部分将在类加载后进入方法区的运行时常量池,相对于class文件具备了动态性,用得多的时string的intern()..关于intern,参见林另一篇博客:

    --------------------------------------------华丽分割线------------------------------------------------------

    对象的创建:

    排除数组和Class对象的创建,普通对象创建过程:

    1:new指令找参数定位常量池中类的符号引用,并检查该类是否加载,解析,初始化过,如果没有,则进行类的加载

    2:对象内存的分配,两个方法:一是通过指针碰撞的无内存碎片方法;二是通过维护一个“”空闲列表“”来分配内存,在分配内存时会遇到多线程安全问题,hotSpot通过基于CAS的乐观锁保证更新操作的原子性

    3:内存分配完成后,对分配的内存空间初始化为零值,不包括对象头,这一步骤保证了对象的实例字段在java中可以不赋初始值就可以使用

    4:设置对象头,包括hashcode,锁的状态,GC分代年龄等....

    5:执<init>方法,根据程序需求进行初始化

    6:创建对象完成

    --------------------------------------------华丽分割线------------------------------------------------------

    对象的内存结构:

    重点在对象头的mark word,多线程会接触到,锁的状态,对象头还有另一部分是对象的类型指针,指向方法区里的对象类型数据

    +实例数据+填充区

    对象的访问:

    hotSpot采用直接指针的方式,即栈中的对象引用指向堆中的对象,堆中对象包括对象实例数据和对象头指向类型数据的指针

    --------------------------------------------华丽分割线------------------------------------------------------

    OutOfMemoryError:

    解决mat插件的问题:无论通过link的方法还是将库文件跟myeclipse合并在一起,都无法解决,最后通过myeclipse的help-->install解决,建议通过这种方法安装插件

    通过-Xmx和-Xms调堆参数,

    通过HeapDumpOnOutOfMemoryError生成快照存储,通过mat分析是内存溢出还是内存泄漏,

    通过-verbose:gc打印GC情况

    public class OOMDump {
    
        static class oomObject{
            
        }
        public static void main(String[] args) {
            List<oomObject> list=new ArrayList<OOMDump.oomObject>();
            while(true){
                list.add(new oomObject());
            }
        }
    }
    View Code

    --------------------------------------------华丽分割线------------------------------------------------------

    StackOverFlowError

    单线程下通过撑爆局部变量来栈内存溢出,一般不刻意设小栈内存够用的

    public class stackoverFlowError {
    
        int stacklength=0;
        public void StackDeepInside(){
            stacklength++;
            StackDeepInside();
        }
        public static void main(String[] args) {
            stackoverFlowError stackoverFlowError=new stackoverFlowError();
            stackoverFlowError.StackDeepInside();
            System.out.println(stackoverFlowError.stacklength);
        }
    }
    View Code

    多线程下每个线程分配的内存大小有限,进程分配内存有限,所以一般刻意烤炉通过减少堆内存来让出内存给栈

    public class StackOOM {
        public void dosomething(){
            while(true){
                
            }
        }
     public void doStackMutiThread(){
         while (true){
             new Thread(new Runnable() {
                
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    dosomething();
                }
            }).start();
         }
     }
     public static void main(String[] args) {
        new StackOOM().doStackMutiThread();
    }
    }
    View Code

    --------------------------------------------华丽分割线------------------------------------------------------

    方法区和运行时常量池的内存溢出:

    1.6以前刻意通过String.intern()来不断创建动态字符串,从而内存溢出(需要改-XX:permSize=10M  -XX:MAxPermSize=10M)

    对于

    String.intern()的理解:

    1.6中:string str=new string("zhu");   str==str.intern()会报false:原因是str是堆中数据,而intern()方法的执行会将第一次遇到的string实例赋值到方法区中,并返回方法区中该副本的引用,而在1.7中,intern()会返回首次遇到的实例在堆中的引用,所以1.7中上段代码为true

    方法区的溢出可以创建大量的Class类填充:大量的jsp文件编译成java类有时会撑爆方法区

    --------------------------------------------华丽分割线------------------------------------------------------

      

  • 相关阅读:
    解读Android 12首个开发者预览版
    Pod创建私有库
    Flutter常用网站
    Flutter常用快捷键
    多个网络请求-并发执行、顺序执行
    小猫爬山问题---贪心算法失效,深度优先搜索优化
    网络基本概念备忘:MAC地址,端口,HTTP状态码
    常见图片文件格式简析
    pdf2xls
    评分卡模型
  • 原文地址:https://www.cnblogs.com/ali-guili/p/9985043.html
Copyright © 2011-2022 走看看