java内存区域与内存溢出异常
java虚拟机自动内存管理机制,不用像C/C++为每一个new操作去写配对delete/free代码
java虚拟机在执行java程序的过程中 会把内存划分为若干个不同的数据区域
程序计数器:执行字节码指令 分支 循环 跳转。
java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的
java虚拟机栈 线程私有,存储局部变量
本地方法栈为native方法服务
java堆 java heap 内存中最大的一块,所有线程共享,此内存区域的唯一目的就是存放对象实例
java堆是垃圾收集器管理的主要区域 DC堆
方法区 method area 存储虚拟机加载的类信息,常量 静态变量
运行时常量池是方法区的一部分
对象的创建 java是一门面向对象的编程语音,new关键字
1.虚拟机收到new指令后,检查这个指令是否能在常量池中定位到一个类的符号引用,是否被加载解析初始化过
2.虚拟机为新生对象分配内存,内存分配后,虚拟机对对象进行必要的设置,例如这个对象是哪个类的实例,如何才能找到类的元数据信息,对象哈希码,这些信息存放在对象的对象头之中(Object header)
3 new指令执行后,会执行方法
OOM
除了程序计数器,虚拟机内存的其他几个运行时区域都有发生outofmemoryerror异常的可能
java堆存储对象实例,在对象数量达到最大堆的容量限制后就会产生内存溢出异常
堆会自动扩展xms xmx
一般的手段是通过内存映像分析工具 eclipse memory analyzer
string.intern() 是一个native方法,如果字符串常量池中已经包含一个等于此string对象的字符串,则返回代表池中这个字符串的string对象
垃圾收集器与内存分配策略
其中程序计数器、虚拟机栈、本地方法栈3个区域随线程而生,随线程而灭
java堆存放几乎所有实例,判断对象是否存活和死去
引用计算算法 引用+1,引用失效-1
可达性分析 ,当一个对象到GC root没用任何引用,即不可,则判定为可回收对象
强引用:GC永远不会回收掉被引用的对象
软引用:还有用并非必须的对象,在发生内存溢出之前,将会把这些对象列进回收范围
弱引用: 无论当前内存是否足够,都会回收掉弱引用关联的对象
执行finalize()方法
新生代GC Minor GC 指发生在新生代的垃圾收集动作,因为java对象大多都具备朝生熄灭的特性,所以minor GC 非常频繁,回收速度快
老年代GC major GC/FULL GC 老年代GC的速度一般回避minorGC 慢十倍以上
大对象直接进入老年代
长期存活的对象进入老年代
类文件结构
代码编译的结果是从本地机器码转变为字节码
java虚拟机不和包括java在内的任何语言绑定,它只与‘CLASS’这种特定的二进制文件格式所关联
任何一门功能性语言都可以表示为一个java虚拟机接受的有效class文件,使用java编译器可以把java代码编译为存储字节码的class文件
虚拟机类加载机制
虚拟机把类的数据从class文件加载到内存,并对数据进行校验,转换解析和初始化,最终可形成可以被虚拟机直接使用的java类型,这就是虚拟机的类加载机制
在java语言里,类型的加载,连接初始化过程都是在程序运行期间完成,虽会令类加载稍微增加一些性能开销,但能提高灵活性。
类从被加载到虚拟机内存中开始,到卸载出内存为止。整个生命周期包括,加载,验证,准备,解析,初始化,使用,卸载
JAVA 内存模型与线程
存储器在容量尤其是访问延时方面的性能增长越来越跟不上处理器性能发展的需要,菜肴层次化的存储器体系结构cache
java内存模型规定了所有的变量都存储在主内存main memory
每条线程还有自己的工作内存 working memory
volatile型变量 ,关键字volatile最轻量级的同步机制 只能保证变量的可见性
java内存模型特征:原子性 在一个操作是不可中断,要么全部执行成功要么全部执行失败,即使多个线程一起执行,也不会被其他线程干扰
可见性:当一个线程修改了这个变量的值,其他线程能立马知道,新值同步回主内存
有序性,线程内观察,所有操作是有序的
java与线程
线程是比进程更轻量级的调度执行单位,线程是CPU调度的基本单位
new新建 运行runable 无限期等待 waiting 阻塞blocked 结束terminated
线程安全和锁优化
线程安全:当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他的协调操作,调用这个对象的行为都可以获得正确的结果。
不可变就是线程安全 final关键字 string就是不可变,调用substring()replace()concat()都不会影响原来的值,只会返回一个新构造的字符串对象
线程安全的实现方法
互斥同步 同步是指多个线程并发访问共享数据时,保证共享数据在同一个时刻只被一个线程使用
在java中,最基本的互斥同步就是synchronized关键字