1 物理内存和虚拟内存
物理内存就是通常所说的RAM(随机存储器),每一个进程在的内存空间在逻辑上是独立的。
虚拟内存:使多个进程在同时运行时可以共享物理内存,但物理内存在逻辑依旧保持独立,还可以扩展内存的地址空间。
2 Java中需要内存的组件
2.1 Java堆:用来保存java对象的内存区域,堆的大小在JVM启动就一次性向操作系统申请完成。-Xmx表示堆的最大大小,-Xms表示初始化大小。内存的管理由JVM控制
2.2 线程:JVM运行实际程序的实体是线程,需要内存保存一些必要的数据。
2.3 类和类加载器
2.4 NIO :一种基于通道和缓冲区来执行IO方式。
2.5 JNI:java在运行时会依赖于JNI代码来实现类库功能,如文件操作、网络IO操作或其他系统调用,JNI也会增加java运行时本机内存占用
3 JVM内存结构
java虚拟机规范中将java运行时数据划分为6种,分别是:
pc寄存器:用于保存单钱正常执行的程勋的内存地址
java栈:每当创建一个线程是,JVM就会为这个线程创建一个对应的java栈,在这个java栈中有多个栈帧,栈帧和每个方法想关联,每运行一个方法就创建一个栈帧,每个栈帧就包含一些内部变量(在方法内定义的变量)、操作栈和方法返回值等信息
堆:保存java对象的区域。每一个存储在堆中java对象都会是这个对象的类的一个副本,他会复制包扣继承自他的父类的所有非静态属性,被所有java线程共享。
方法区:保存类结构信息的地方
运行时常量池
本地方法栈
4 JVM内存分配策略
堆中存放对象,栈主要用来执行程序
5 JVM内存回收策略
5.1静态内存的分配和回收
静态内存分配指java被编译时就去等需要的内存空间,当程序被加载时系统一次性的分配给,直到程序执行完毕释放
5.2动态内存分配和回收—垃圾收集器
如何检测垃圾:只要某个对象不再被其他活动的对象引用,这个对象就可以被回收
根对象:
a在方法中局部变量区的对象的引用
b在java操作栈中的对象的引用:有些对象是直接在操作栈中持有的,所有操作栈肯定也包含根对象集合
c在常量池中对象的引用
d在本地方法中持有的对象的引用
e类的Class对象
5.3基于分代的垃圾收集算法
hotsopt中基于分代的垃圾收集方式:把对象按照寿命长短进行分组,分为年轻代和年老代,新创建的对象被分年轻代,如果对象经过几次回收依然存活,那么在把这个对象划分到年老代。年老代收集频率没有年轻代频繁,这样就减少了每次垃圾收集时要扫描的对象数量,提高回收效率
JVM将整个堆分为Young、Old和Perm区,分别存放不同年龄的队形
young区又分eden和survivor区,其中所有新建的对象都在Eden区,当eden区满后触发minor GC将eden区仍然存活的对象复制到其中一个survivor区,另外一个survivor区中存活的对象也复制到这个survivor中,保证只有一个survivor区是空的
old区存放young区survivor区满后触发minorGC后存活对象,当edenu满后把对象存入survivor区,如果survivor区对象满了,gc收集器把队形直接存放old区,如果old区满,直接触发FullGC,回收整个堆内存
6内存问题分析
a GC日志分析
查看gc的频度和每次gc回收了哪些内存
b堆内存快照文件
cJVM Crash日志分析