1、java内存区按粗略的分,分为堆内存和栈内存,java虚拟机栈(Stack)和java堆(Heap)的区别:
(1)栈是线程私有的,堆是线程共享的
(2)栈存储局部变量表(局部变量表用来存储基本数据类型,对象引用)、操作数栈、动态链接,方法出口等信息;堆用来分配对象实例和数组,也是垃圾收集器管理的主要区域(GC)
2、堆和方法区(Method Area)的区别:
(1)堆用来分配对象实例和数组;方法区用来存储类信息、常量、静态变量、即时编译器编译后的代码。
(2)堆分为年轻代和年老带;方法区为永久代
3、常量池和堆的区别:
见http://blog.csdn.net/soonfly/article/details/70147205
4、对象的访问方式分为:
(1)句柄访问:优势为reference本身不需要修改
(2)指针访问:速度快
5、对象的内存布局分为3块区域:
(1)对象头:一部分用来存储对象自身的运行时数据(包括哈希码,GC分代年龄等),另一部分为类型指针
(2)实例数据:存储各种类型的字段内容
(3)对齐填充:没有特别含义,仅仅起到占位符的作用
6、虚拟机中内存分配:
(1) 操作系统分配给每个进程的内存是有限的,例如32位windows限制为2GB,Xmx为最大堆容量,MaxPermSize为最大方法区容量,程序计数器消耗内存很小可以忽略,剩下的内存就由虚拟机栈和本地方法栈瓜分了。
(2)因此,每个线程分配的栈容量越大,可以建立的线程数量自然就越小,建立线程时就越容易将剩下的虚拟机栈和本地方栈的锁占有的内存耗尽,就会出现StackOverFlowError,因此开发多线程要特别注意。
(3)如果多线程导致内存溢出,在不能减少线程数和更换64位虚拟机的情况下,就只能减少最大堆容量和减少栈容量来换取更多线程。
7、垃圾收集器与内存分配策略
(1)程序计数器,虚拟机栈、本地方法栈,随线程而生,随线程而灭,因此这3个区域不用考虑内存回收的问题。
(2)java堆和方法区的内存的分配和回收都是动态的,因此垃圾收集器关注的是这一部分的内存,内存的分配和回收也指的是这一部分内存。
(3)可达性分析算法:
作用:用来判定对象是否存活;
思路:通过一系列的称为“GC Roots”的对象作为起始点,向下搜索,搜索的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连时,则这个对象不可用,可以判定为可回收对象。
(4)方法区(即HotSpot虚拟机中的永久代)的垃圾回收两部分内容:回收废弃常量和无用的类。
无用的类要满足三个条件才会是无用的类:一是该类的所有实例都会被回收;二是加载该类的ClassLoader已经被回收;三是该类对应的java.lang.Class没有被任何地方引用。
8、OutOfMemoryError异常:简称OOM异常
(1)java堆溢出:java.lang.OutOfMemoryError:Java Heap Space
-Xms和-Xmx堆的最小值和最大值
解决方法:首先确认是内存泄漏还是内存溢出:
内存泄漏:是垃圾收集器无法回收对象;
解决方法:查看对象到GC Roots的引用链;
内存溢出:内存中的对象必须还活着;
解决办法:调整-Xms和-Xmx,从代码上检查某对象生命周期是否过长,持有状态是否过长;减少程序运行区的内存消耗
(2)虚拟机栈和本地方法栈的溢出:
栈容量由-Xss设定
StackOverFlowError:线程请求栈深度大于虚拟机所允许的最大深度。一般出现在单线程
解决方法:阅读错误栈
OutOfMemoryError:虚拟机在扩展栈时无法申请到足够的内存空间。一般出现在多线程。
解决方法:在不能减少线程数或者更换64位虚拟机的情况下,可以减少最大堆和减少栈容量获取更多线程;
(3)方法区和运行时常量池溢出:
java.lang.OutOfMemoryError:PermGen space
解决办法:调整-XX:PermSize和-XX:MaxPermSize
例如:-Xms8g -Xmx12g -XX:MaxPermSize=8g
(4)本机直接内存溢出:
本机直接内存可以通过-XX:MaxDirectoryMemory指定,如果不指定,则默认与堆最大值-Xmx一样
9、吞吐量:
吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间)
如果虚拟机运行100分钟,垃圾收集花了1分钟,那吞吐量就是99%,垃圾收集的停顿时间越短越适合需要与用户交互的程序,良好的响应速度可以提高用户体验,而高吞吐量则可以高效的利用CPU的时间尽快完成程序的计算任务,适合在后台运算而不需要与用户有过多交互的任务。
10、CMS:并发低停顿垃圾收集器
11、
新生代GC(Minor GC):指的是发生在新生代的垃圾收集动作,因为java对象大部分具备朝生夕灭的的特性,因此Minor GC非常频繁,回收速度也较快
老年代GC(Major GC/Full GC):指的是发生在老年代的GC,Major GC一般也会伴随Minor GC(但非绝对),Major GC速度要比Minor GC慢10倍以上。
12、接口和类在类加载过程的区别:
当一个类在初始化时要求其父类全部都已经初始化过了,但是当一个接口初始化时,并不要求其父类全部都初始化完,只有在真正使用到父接口时才会初始化。
13、类加载过程:
加载、验证、准备、解析、初始化
14、初始化:
<1>静态语句块只能访问定义在静态语句块之前的变量,定义在它之后的变量,在前面的静态语句块可以赋值,但是不能访问
public class Test{
static{
i=0;//可以赋值
System.out.println(i);//不能引用,会提示“非法向前引用”
}
static int i=1;
}
15、
(32位系统):
Java一共有8种基本数据类型(原始数据类型):
类型 存储要求 范围(包含) 默认值 包装类
整 int 4字节(32位) -231~ 231-1 0 Integer
数 short 2字节(16位) -215~215-1 0 Short
类 long 8字节(64位) -263~263-1 0 Long
型 byte 1字节(8位) -27~27-1 0 Byte
浮点 float 4字节(32位) -3.4e+38 ~ 3.4e+38 0.0f Float
类型 double 8字节(64位) -1.7e+308 ~ 1.7e+308 0 Double
字符 char 2字节(16位) u0000~uFFFF(‘’~‘?’) ‘0’ Character
(0~216-1(65535))
布尔 boolean 1/8字节(1位) true, false FALSE Boolean