目录:
1.Java虚拟机
栈区:
1.每个线程包含一个栈区,栈中只保存原始类型数据和对象和对象引用(不是对象),对象都存放在堆区中
2.每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
3.栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。
方法区:
1.又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的class和static变量。
2.方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。
每一个Java线程都有一个程序计数器来用于保存程序执行到当前方法的哪一个指令
Java堆内存
所有通过new创建的对象的内存都在堆中分配,其大小可以通过-Xmx和-Xms来控制
Heap区分两大块,一块是NEWGeneration,另一块是OldGeneration.
NewGeneration中,有一个叫Eden的空间,主要是用来存放新生的对象,还有两个SurvivorSpaces(from,to),它们用来存放每次垃圾回收后存活下来的对象。
OldGeneration中,主要存放应用程序中生命周期长的JVM内存对象。
PermanentGeneration,又称非堆,主要用来放JVM自己的 反射对象,比如类对象和方法对象等
2.垃圾回收机制
目的:于清除不再使用的对象
触发条件:
如何回收不存活的对象?• 根搜索算法确定一系列的GC Root的对象作为起点,从这些节点向下搜索,搜索的路径称为引用链(Reference Chain),当一个对象无法通过引用链连向GC Root的话证明此对象是不可用的
• GC Root 的确定1 虚拟机栈中引用的对象
2 方法区中的类静态属性引用的对象
3 方法区中常量引用的属性
4 本地方法栈中Native方法的引用的对象
如何减少GC开销?• 如果一个对象在搜索后发现没有与 GC Roots 相连接的引用链,就会被第一次标记并且进行一次筛选,看此对象是否有必要执行 finalize() 方法•• 如果 finalize 方法没有被覆盖或者已经被虚拟机调用过了则将此对象删掉否则此对象将被放入一个名为 F-Queue 的队列之中•• 虚拟机会自动建立一条低优先级的 Finalizer 线程去执行这个对象的 finalize 方法•• 如果此次执行该对象还没有与 GC Roots 建立引用链则会在下次 gc 的时候被删除
内存泄露/内存溢出• 不要显式调用 System.gc ()• 尽量减少临时对象的使用• 对象不用时最好显式置为 null• 尽量使用 StringBuffer , 而不用 String 来累加字符串• 能用基本类型如 int,long , 就不用 Integer,Long 对象• 尽量少用静态对象变量• 分散对象创建或删除的时间
3.内存泄露检测工具• 内存泄漏大量无用且可达的对象,不能被GC回收
•• 内存溢出java.lang.OutOfMemoryError:PermGenspace
在JVM中如果98%的时间是用于GC且可用的Heap size 不足2%的时候将抛出此异常信息。
JVM初始分配的内存由-Xms指定,默认是物理内存的1/64;
JVM最大分配的内存由-Xmx指定,默认是物理内存的1/4。
Jconsole、Visual VM、JProfiler
jps、jmap、jstat、jstack、jinfo
3.1 jmap
-heap:打印jvm heap的情况
-histo:打印jvm heap的直方图。其输出信息包括类名,对象数量,对象占用大小
-histo:live:同上,但是只答应存活对象的情况
-permstat:打印permanent generation heap情况
#instance是对象的实例个数
#bytes是总占用的字节数
classname对应的就是Class文件里的class的标识
B代表byte
C代表char
D代表double
F代表float
I代表int
J代表long
Z代表boolean
前边有[代表数组,[I就相当于int[]
对象用[L+类名表示
3.2 Jstack
1、NEW,线程对象被new出来,但是还没有调用start方法,这时就被称为NEW;
2、RUNNABLE,线程对象已经被调用了start方法,但是,这个线程的run方法可能运行也可能没有运行,依赖于操作系统的行为;
3、BLOCKED,简单的说,线程进入了synchronized关键字标识的同步块,但和4状态有所区别;
4、WAITING和TIMED_WAITING差不多,一般是调用了对象的wait方法,需要其它线程在特定场景使用notify/notifyAll方法;
5、TERMINATED,run方法退出运行,即进入这个状态;
3.3 Jstat
S0:Heap上的 Survivorspace 0 段已使用空间的百分比
S1:Heap上的 Survivorspace 1 段已使用空间的百分比
E: Heap上的 Edenspace 段已使用空间的百分比
O: Heap上的 Oldspace 段已使用空间的百分比
P: Permspace 已使用空间的百分比
YGC:从程序启动到采样时发生Young GC的次数
YGCT:YoungGC所用的时间(单位秒)
FGC:从程序启动到采样时发生Full GC的次数
FGCT:FullGC所用的时间(单位秒)
GCT:用于垃圾回收的总时间(单位秒)
如何避免内存泄露/溢出
内存泄漏解决方案
1) 设置-Xms、-Xmx相等
2)设置NewSize、MaxNewSize相等
3)设置Heap size, PermGenspace
Tomcat的配置示例:修改 %TOMCAT_HOME%/bin/catalina.bat orcatalina.sh
在“echo"Using CATALINA_BASE: $CATALINA_BASE"”上面加入以下行:
Cmd代码: set JAVA_OPTS=-Xms800m -Xmx800m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=256m