• 基于虚拟机实例/java程序线程的虚拟机内存分配


           一个运行时的java虚拟机实例的天职就是:负责运行一个java程序。当启动一个java程序时,一个虚拟机实例也就诞生了。当该java程序关闭退出,这个虚拟机实例也就随之消亡。如果在同一台计算机上同时运行三个java程序,将得到三个java虚拟机实例。每个java程序都运行于它自己的java虚拟机实例中。虚拟机实例通过调用某个初始类的main()方法来运行一个java程序。

           命令行:java   Echo   Greetings,Planet. 第一个单词java,告诉操作系统应该运行虚拟机,第二个词指出了初始类的名字,剩下的单词序列作为该程序的命令行参数以字符串数组的形式传递给main()。

           java程序初始类中的main()方法,将作为该程序初始线程的起点。任何其他线程都是由这个初始线程启动的。

           虚拟机内部有两种线程:守护线程和非守护线程。守护线程通常是虚拟机自己使用的,比如执行垃圾回收任务的线程。java程序中的线程如开始于main()方法的线程和在程序中创建的其他线程都是非守护线程。java程序也可以把它创建的任何线程标记为守护线程。程序中所有非守护线程都终止时(程序运行结束),虚拟机实例将自动退出(因此不是所有服务都可以交给守护线程来处理,比如读写操作和逻辑计算,守护线程还没来得及进行可能虚拟机已经退出了)。如果main方法中未调用其他的线程,main方法返回这就意味着终止了程序中唯一的非守护线程,最终导致虚拟机实例退出。

          非守护线程转守护线程:线程对象在执行start()方法前执行setDaemon(true)方法即可。

           每个虚拟机都有一个类装载子系统,它根据给定的全限定名来装载类或接口,同样,每个虚拟机有一个执行引擎,负责执行包含在被装载类的方法中的指令。当虚拟机运行一个程序时,需要内存来存储许多东西,字节码、class文件中的其他信息、程序创建的对象、传递给方法的参数、返回值、局部变量以及运算的中间结果,虚拟机把这些东西都组织到几个“运行时数据区”,以便于管理。

           某些运行时数据区是由虚拟机实例运行的程序中所有线程共享的,某些运行时数据区则只能由一个线程拥有(内存分配的基础角度是虚拟机实例或线程),每个虚拟机实例有一个方法区和堆(意味着该虚拟机实例中java程序创建的所有线程都只有一个共同的方法区和堆,所有线程涉及到的所有类只有这一个方法区和堆),方法区和堆被虚拟机实例中的所有线程(应该包括守护线程)共享。虚拟机装载一个class文件时会从该文件的二进制数据中解析类型信息,并把这些类型信息存放到方法区。程序运行时,虚拟机会把程序运行时创建的对象存放到堆中。由于方法区和堆是java程序的所有线程共享的,因此对方法区和堆中的数据的访问必须设计为线程安全的。每一个新线程被创建时将得到自己的PC寄存器(程序计数器)和一个java栈。如果线程正在执行一个java方法(非本地方法),PC寄存器的值总是指示下一条将被执行的字节码指令的地址java栈由栈帧/帧组成,一个栈帧对应一个方法,包含一个java方法的调用状态(局部变量(表),操作数栈,动态链接,方法出口),线程调用某个java方法时,虚拟机将一个新的栈帧压入到该线程的java栈中,当该方法返回时,这个栈帧被弹出,抛弃。java栈都是向下生产的,因此栈顶都在底部,底部的栈顶正是压栈出栈的操作地

           关于方法区:虚拟机装载某个类时先使用类装载器定位到相应的class文件,然后以线性二进制流的形式将其读入到虚拟机,紧接着虚拟机读取其中的类型信息(包括类变量/静态变量)并将其存入到方法区(可以理解为class文件对应的所有信息被保存在方法区)。当虚拟机运行程序时会去查找和使用存储在方法区中的类型信息。方法区可以被垃圾收集,当某个类变成不再被引用,虚拟机可以卸载这个类(垃圾收集),从而使方法区占据的内存最小。类变量是由所有类实例共享的,但即使没有实例它也可以被访问,因此类变量也存储在方法区

           虚拟机规范把方法区描述为堆的一个逻辑部分,别名叫非堆区,目的是跟java堆区分开来。

           习惯使用HotSpot虚拟机的开发者更愿意把方法区称为永久代,仅仅是因为hotspot把GC分代收集扩展至方法区,或者说使用永久代来实现方法区而已。但使用永久代来实现方法区容易遇到内存溢出问题(永久代有-XX:MaxPermSize的上限)。

           字长的考量:虚拟机中基本的数据单元是字,它的大小由虚拟机实现的设计者决定,但至少应该一个字足以持有byte、short、int、char、float型和reference引用型的值,两个字单元足以持有long、double型的值。class文件中方法属性中局部变量所需空间大小也是以字为单位。

    新生的小心情
  • 相关阅读:
    spring + spring mvc + mybatis + react + reflux + webpack Web
    陈忠实和路遥:日他妈的文学和你懂个锤子
    Spring+SpringMVC+MyBatis+easyUI整合基础篇
    JAVA方法中的参数用final来修饰的效果
    全球晶圆代工厂哪家强?2016年Top30名单
    EXT combobox 二级连动 清空store缓存数据
    潘通
    MySQL性能优化
    启用了不安全的HTTP方法
    Hibernate一级缓存(基于查询分析)
  • 原文地址:https://www.cnblogs.com/jianmianruxin/p/6933394.html
Copyright © 2020-2023  润新知