zoukankan      html  css  js  c++  java
  • jvm02

    java虚拟机内存管理

    每个线程就是一个顺序的执行单元,线程共享区即多个线程共享同一块区域,线程独占区即每个线程都有自己的虚拟机栈,本地方法栈,程序计数器。

    程序计数器是一个比较小的内存空间,可以看作是当前线程所执行的字节码的行号指示器,位于线程独占区,如果线程执行的是java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址,如果执行的是native方法,计数器的值为underfined

    Java虚拟机栈

    虚拟机描述的是java方法执行的动态内存模型

    栈帧

    每个方法执行,都会创建一个栈帧,伴随着方法从创建到执行完成,用于存储变量表,操作数栈,动态链接,方法出口等。

    局部变量表

    存储编译期可知的各种基本数据类型,引用类型,returnAddress类型,

    局部变量表的内存空间在编译期完成分配,当进入一个方法,这方法需要在帧分配多少内存是固定的,在方法运行期是不会改变局部变量表的大小(存储的只是对象的引用)

     1 public class Demo {
     2     
     3     public void tes() {
     4         System.out.println("方法执行....");
     5         tes();
     6     }
     7     
     8     public static void main(String[] args) {
     9         new Demo().tes();
    10         
    11     }
    12 
    13 }

    方法执行....
    方法执行....

    ........

    Exception in thread "main" java.lang.StackOverflowError

    若不限定栈的内存,将超过虚拟机的内存,或物理内存,将抛出 OutofMemory

    本地方法栈

    虚拟机栈为虚拟机执行java方法服务,本地方法栈为虚拟机执行native方法服务

    java堆

    存储对象实例

    垃圾收集器管理的主要区域

    新生代,老年代

    方法区

    存储虚拟机加载的类信息(类的版本,字段,方法,接口),常量,静态变量,即使编译器编译后的代码等数据。

    方法区和永久代

    垃圾回收在方法区的行为(针对常量池的回收以及对象类型的卸载等)

    异常的定义

    OurOfMemoryError

    运行时常量池,属于方法区的

     1 public class Test {
     2     
     3     public static void main(String[] args) {
     4         String s1 = "abc";//字节码常量
     5         String s2 = "abc";//字节码常量  
     6         System.out.println(s1 == s2);
     7         
     8         String s3 = new String("abc");
     9         
    10         System.out.println(s1 == s3);
    11         
    12         System.out.println(s1 == s3.intern());//运行时常量  
    13         
    14     }
    15     
    16     /**
    17      *  true
    18         false
    19         true
    20      */
    21 }

    任何字符串的创建都会放在常量池中,常量池在方法区中,运行时常量池维护了StringTable字符串表,数据类型可以是HashSet ,存放所实例的字符串对象,由于hashSet的无序和不可重复, abc 只创建了一个实例,即 s1 == s2

    如果用new 创建一个对象一定是在堆内存开辟空间,不再考虑常量池的问题

    intern()作用在jdk1.7之后是查看常量池中是否存在和调用方法的字符串内容一样的字符串,如果有的话,就返回该常量池中的字符串,若没有的话,就在常量池中写入一个堆中该字符串对象的一个引用,指向堆中的该对象,并返回该引用。即是调用这个方法之后把字符串对象加入常量池中。

    直接内存

    能够分配堆外内存,不受到java虚拟机内存的制约,会受到当前操作系统物理内存的制约

    对象的结构:

    Header 对象头

      自身运行时数据(Mark Word)

        哈希值 GC分代年龄 锁状态标志 线程持有的索 偏向线程ID 偏向时间戳 

      类型指针

        对象指向它类的元数据的指针

    InstanceData(相同的字段分配在一起)

      Long dobles    shorts/chars  

    Padding,对齐填充不是必须的,占位符,对象的大小必须是8个字节的整数倍。

    对象的访问定位

      使用句柄:指向堆中的句柄池,保存了实例对象的地址,引用地址不需要修改。

      直接指针,从引用类型直接指向真正的内存区域,速度快,性能高

    两者都要保存  到对象实例数据的指针和到对象类型数据的指针

      

  • 相关阅读:
    常用正则表达式
    在过滤器中设置一个应用范围内的路径
    在过滤器中设置一个应用范围内的路径
    shell編程之遠程開啓多個機器的ElasticSearch
    shell之CMD的使用,是用` `還是" "?
    shell編程之自動化集群搭建並啓動
    shell編程之權限
    登录用户出现‘’-bash-4.2$‘’的问题解决
    locate: can not open `/var/lib/mlocate/mlocate.db': No such file or directory
    Spring之mvc應用(包含aop)
  • 原文地址:https://www.cnblogs.com/quyangyang/p/10997167.html
Copyright © 2011-2022 走看看