# jvm

将.java文件通过javac命令编译成机器可识别的字节码文件(.class),通过类装载子系统加载到内存区(主要是加载到方法区)

image-20200304120821268

# JVM内存模型(运行时数据区)

JVM内存空间分为五部分,分别是:方法区、堆、Java虚拟机栈、本地方法栈、程序计数器

其中Java虚拟机栈、本地方法栈、程序计数器是每个线程独享的,方法区和堆是共享的

# 堆:

1.用来存放对象的 被线程共享的(被栈使用) 2.堆又可以分为新生代和老年代,实际还有一个区域叫永久代,但是jdk1.7已经去永久代了,所以可以当作没有,永久代是当jvm启动时就存放的JDK自身的类和接口数据,关闭则释放。

新生代(minor GC)可以分为Eden区和两个幸存区(survivor),这么设计是为了更好地利用内存

使用的是复制回收算法,两个幸存区是较小的区域。逻辑是每次使用Eden区和其中一个幸存区,回收时将其还存活着的对象一次性的复制到另一个幸存区中,最后清理到刚才使用的Eden和其中一个幸存区。执行15次后悔被移到老年代

新建对象就在Eden区。但是并不是对象最活跃的区域,对象最活跃的区域是老年代,因为经过各种垃圾回收之后对象都跑到这里来了。

3.内存溢出 内存溢出其实没什么好讲的,满了就会溢出。怎么才能满呢,不断创建对象,那问题又来了,创建多了被回收怎么办,好办,将新建的对象存到list里去,就不会回收了,为什么呢,因为jvm判定一个对象的死活就是根据对象是不是被引用。 此外堆跟随jvm的,有jvm就有堆。堆也是垃圾回收的主要区域,又叫GC堆,垃圾堆,玩笑。

# 方法区:

1.8称为元空间 。主要存放常量,静态变量,类信息

# 本地方法栈:

C语言实现的,新系统与老系统之间进行交互,方法有navite标识,每个方法独有的,目前已不用

例如:private navite void start();

# 程序计数器:

在每个线程都有,指向当前线程执行的位置

作用:当cpu资源被别的线程释放后定位之前的位置

字节码执行引擎 会动态修改程序计数器

# 栈(线程)

主要由四部分组成:局部变量,操作数栈,动态链接,方法出口

栈会给每个线程创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息

先进后出:先执行main方法,然后调用方法,方法执行完销毁,最后在销毁main方法

# 1局部变量:

称之为本地变量表,它包含在一个独立的栈帧中。主要用于存储方法参数和定义在方法体内的局部变量

# 2 操作数栈:

临时的内存空间,所有的变量的值或运算的值都会先存在操作数栈,在局部变量为变量分配内存空间,然后再将操作数栈的值存入局部变量

如 int i = 1; 就是将int类型的操作数1压入栈,在局部变量为i分配内存空间,将1存入局部变量

# 3动态链接:

将方法区里面的符号引用转为直接引用

# 4方法出口:

指向返回main方法后所对应的位置

# JVM虚拟机调优

STW :stop the world full gc 会停止所有的当前所有线程进行gc,会造成网站卡顿

Eden和幸存区的比:8:1:1

为了减少STW 发生的概率(full GC次数),减少一次full GC的时间

解决方案1:扩大幸存区大小,Eden区和幸存区复制到另一个幸存区是内存大小大于另一个幸存区50%会直接放到老年代

1、一般初始堆和最大堆设置一样,这两个值设置相同,以避免每次垃圾回收完成后JVM重新分配内存。

64位系统理论上可以设置为无限大,但是一般设置为4G,因为如果再大,JVM进行垃圾回收出现的暂停时间会比较长,这样全GC过长,影响JVM对外提供服务,所以不能太大。一般设置为4G。 2、-XX:NewRaio和-XX:SurvivorRatio这两个参数,都是设置年轻代和年老代的大小的,设置一个即可,第一是设置年轻代的大小,第二个是设置比值,理论上设置一个既可以满足需求

javap 对java代码进行反汇编

# jvm指令手册

安装 visual Gc

jvm数据原子操作

image-20200304130553218

# 内存模型、类加载机制以及性能优化

Java堆栈 http://blog.csdn.net/huozhicheng/article/details/6575960 在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配。 当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。 堆内存用来存放由new创建的对象和数组。 在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。 引用变量就相当于是为数组或对象起的一个名称,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或对象。

堆,队列优先,先进先出,栈,先进后出