jvm

JVM体系结构 内存模型
JVM垃圾收集算法:
JVM内存管理:深入Java内存区域与OOM
JVM 堆内存设置原理
JVM内存区域模型:
1.程序计数器
每个Java线程都有一个程序计数器来用于保存程序执行到当前方法的哪一个指令(只有此不会产生OutOfMemoryError)
2.Java虚拟机栈
Java虚拟机栈生命周期也是与线程相同,在VM Spec中对这个区域规定了2中异常状况:如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;如果VM栈可以动态扩展(VM Spec中允许固定长度的VM栈),当扩展时无法申请到足够内存则抛出OutOfMemoryError异常。
-Xss 设置栈 大小
3.本地方法栈
为虚拟机使用到的Native方法服务,Hotspot虚拟机并不区分VM栈和本地方法栈
4.Java堆
是虚拟机管理最大的一块内存。Java堆是被所有线程共享的,唯一目的就是存放对象实例
-Xms20m -Xmx20m 设置堆 大小
5.方法区
存放了每个Class的结构信息,包括常量池、字段描述、方法描述
-MaxPermSize(最大方法区)
-XX:PermSize=10M -XX:MaxPermSize=10M 常量池大小设置
6 直接内存
不是虚拟机运行时数据区的一部分,它根本就是本机内存而不是VM直接管理的区域
-XX:MaxDirectMemorySize指定,不指定的话默认与Java堆(-Xmx指定)一样

Java堆和栈的区别
  Java把内存划分成两种:一种是栈内存,一种是堆内存。
  在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配。当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。
  堆内存用来存放由new创建的对象和数组。在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。在堆中产生了一个数组或对象后,还可以在栈中定义一个特殊的变量,让栈中这个变量的取值等于数组或对象在堆内存中的首地址,在栈中的这个特殊的变量就变成了数组或者对象的引用变量,以后就可以在程序中使用栈内存中的引用变量来访问堆中的数组或者对象,引用变量相当于为数组或者对象起的一个别名,或者代号。
  引用变量是普通变量,定义时在栈中分配内存,引用变量在程序运行到作用域外释放。而数组&对象本身在堆中分配,即使程序运行到使用new产生数组和对象的语句所在地代码块之外,数组和对象本身占用的堆内存也不会被释放,数组和对象在没有引用变量指向它的时候,才变成垃圾,不能再被使用,但是仍然占着内存,在随后的一个不确定的时间被垃圾回收器释放掉。这个也是java比较占内存的主要原因。但是在写程序的时候,可以人为的控制。

4.Java类加载机制
  JVM将类加载过程划分为三个步骤:装载、链接和初始化。
装载(Load):装载过程负责找到二进制字节码并加载至JVM中,JVM通过类的全限定名(com.bluedavy. HelloWorld)及类加载器(ClassLoaderA实例)完成类的加载;
链接(Link):链接过程负责对二进制字节码的格式进行校验、初始化装载类中的静态变量及解析类中调用的接口、类;
初始化(Initialize):执行类中的静态初始化代码、构造器代码及静态属性的初始化。
5.内存回收
  收集器:引用计数收集器、跟踪收集器
引用计数收集器:对于Java这种面向对象的会形成复杂引用关系(如ObjectB和ObjectC互相引用)的语言而言,引用计数收集器不是非常适合,Sun JDK在实现GC时也未采用这种方式。
跟踪收集器实现算法:复制(Copying)、标记-清除(Mark-Sweep)和标记-压缩(Mark-Compact)
  复制:当要回收的空间中存活对象较少时,复制算法会比较高效,其带来的成本是要增加一块空的内存空间及进行对象的移动。
  标记-清除:在空间中存活对象较多的情况下较为高效,但由于标记-清除采用的为直接回收不存活对象所占用的内存,因此会造成内存碎片。
  标记-压缩:在标记-清除的基础上还须进行对象的移动,成本相对更高,好处则是不产生内存碎片
  JVM

原文地址:https://www.cnblogs.com/luleiitlife/p/8545076.html