JVM 深入浅出
jvm 相信大家都有认知 在面试中也是经常遇见的希望接下来的这篇文章可以对你们带来帮助
java 的好处 :
java这门语言之所以受广大的码农所喜爱是因为它不像C语言需要程序员自己手动分配内存空间 java 100% 专注让程序员业务代码 ,而c语言需要50%关注内存的分配
话不多说 先来一道面试题:
在运行时数据区 哪些是线程是共享的哪些线程私有的
- 线程共享的包括 :堆和 方法区
- 线程私有的包括 :虚拟机栈 本地方法栈 程序计数器
程序计数器:指向当前线程正在执行的字节码指令的地址也就是 执行到哪一行的行号 唯一的一个不会导致 OutofMemoryError
虚拟机栈 :基本数据类型和对象的引用变量都存在此区域 栈是一种数据结构 先进后出,后进先出 一个方法就是一个栈 栈的单位是栈帧
本地方法栈
简单点说就是 底层用native修饰的 底层已经用c语言进行编写的
方法区 :
- 所有线程共享;
- 方法(包含构造),接口,定义在此区域
- 所有方法的信息;
- 静态常量类信息+方法信息+常量池
- 在jdk1.8以后 常量不再存储在方法区了 而存储在接下来要说的堆中
堆
堆可以说是最繁琐的了 因为它里面包括了一些特别的饿数据结构和算法
所有对象的实例和数组开辟的空间都在此区域保存 所有线程共享
堆分区: (他们的比例8:1:1)
- 新生代
2.老年代
3.永久代
Java中内存分配机制
核心:分代分配,分代回收,分代整理
新生代(Young Generation)
说到JVM 不得不提的两个异常
StackOverFlowerror
线程请求的栈的深度大于虚拟机栈规定的深度
OutofMemoryError
虚拟机在扩展栈时,无法申请到足够的内存空间
GC的深入浅出
垃圾回收机制的定义
在java程序运行过程中 jvm有一个专门负责回收那些不再使用的对象所占有的内存这种回收 过程我们称之为垃圾回收机制
对象的状态
在java虚拟机的垃圾回收器来看,堆中的对象有三种状态
01 可触及状态
02 可复活状态
03 不可触及状态
只有对象处于不可触及状态的时候,垃圾回收期才会真正的师傅对象所占的内存
对象的生命周期开始(new语句 或者反射中的newInstance) 可触及状态
对象不再被引用,或者对象调用了finallize() 可复活状态
对象调用了finalize() 不可触及状态
垃圾回收
对象的生命周期结束
垃圾何时被回收(触发GC 的条件)
对象没有引用====>对象处于不可触及的状态
程序在作用域正常执行之后
System.exie()
程序以外终止
什么时间==触发GC条件
- System.gc()可能触发
- 系统自身决定GC的触发时间
- 根据Eden区和FromSpace区的内存大小来决定对什么东西
JVM GC回收哪个区域的垃圾?
需要注意的是,JVM GC只回收堆区和方法区内的对象。而栈区的数据,在超出作用域后会被JVM自动释放掉,所以其不在JVM GC的管理范围内。
JVM GC怎么判断对象可以被回收?
1. 对象没有引用
2. 作用域发生未捕获异常
3. 程序在作用域正常执行完毕
4. 程序执行了System.exit()
5. 程序发生意外终止(被杀线程等)
6. 在Java程序中不能显示的分配和注销缓存,因为这些事情JVM都帮我们做了,那就是GC。有时候我们可以将相关的对象设置成null来试图显式的清楚缓存,但是并不是设置成null就会一定被标记成可回收,有可能发生逃逸。将对象设置成null至少没有什么坏处,但是使用System.gc()便不可取了,使用System.gc()时并不是马上执行GC操作,而是会等待一段时间,甚至不执行,而且System.gc()如果被执行,会触发Full GC,这非常影响性能。
JVM GC什么时候执行?
eden区空间不够存放新对象的时候,执行Minro GC。升到老年代的对象大于老年代剩余空间的时候执行Full GC,小于时被HandlePromotionFailure参数强制full gc。调优主要是减少Full GC的触发次数,可以通过NewRatio控制新生代转老年代的比例,通过Max Tenuring Threshold设置对象进入老年代的年龄阀值。
减少GC开销的措施
根据上述GC的机制,程序的运行会直接影响系统环境的变化,从而影响GC的触发。若不针对GC的特点进行设计和编码,就会出现内存驻留等一系列负面影响。为了避免这些影响,基本的原则就是尽可能地减少垃圾和减少GC过程中的开销。具体措施包括以下几个方面:
(1) 不要显式调用System.gc()
此函数建议JVM进行主GC,虽然只是建议而非一定,但很多情况下它会触发主GC,从而增加主GC的频率,也即增加了间歇性停顿的次数。
(2) 尽量减少临时对象的使用
临时对象在跳出函数调用后,会成为垃圾,少用临时变量就相当于减少了垃圾的产生,从而延长了出现上述第二个触发条件出现的时间,减少了主GC的机会。
(3) 对象不用时最好显式置为Null
一般而言,为Null的对象都会被作为垃圾处理,所以将不用的对象显式地设为Null,有利于GC收集器判定垃圾,从而提高了GC的效率。
(4) 尽量使用StringBuffer,而不用String来累加字符串
由于String是固定长的字符串对象,累加String对象时,并非在一个String对象中扩增,而是重新创建新的String对象,如Str5=Str1+Str2+Str3+Str4,这条语句执行过程中会产生多个垃圾对象,因为对次作“+”操作时都必须创建新的String对象,但这些过渡对象对系统来说是没有实际意义的,只会增加更多的垃圾。避免这种情况可以改用StringBuffer来累加字符串,因StringBuffer是可变长的,它在原有基础上进行扩增,不会产生中间对象。
(5) 能用基本类型如Int,Long,就不用Integer,Long对象
基本类型变量占用的内存资源比相应对象占用的少得多,如果没有必要,最好使用基本变量。
(6) 尽量少用静态对象变量
静态变量属于全局变量,不会被GC回收,它们会一直占用内存。
(7) 分散对象创建或删除的时间
集中在短时间内大量创建新对象,特别是大对象,会导致突然需要大量内存,JVM在面临这种情况时,只能进行主GC,以回收内存或整合内存碎片,从而增加主GC的频率。集中删除对象,道理也是一样的。它使得突然出现了大量的垃圾对象,空闲空间必然减少,从而大大增加了下一次创建新对象时强制主GC的机会。
JVM 深入浅出的更多相关文章
- Java开发人员必备十大工具
Java世界中存在着很多工具,从著名的IDE(例如Eclipse,NetBeans和IntelliJ IDEA)到JVM profiling和监视工具(例如JConsole,VisualVM,Ecli ...
- 深入浅出 JVM GC(3)
# 前言 在 深入浅出 JVM GC(2) 中,我们介绍了一些 GC 算法,GC 名词,同时也留下了一个问题,就是每个 GC 收集器的具体作用.有哪些 GC 收集器呢? Serial 串行收集器(只适 ...
- 深入浅出 JVM GC(2)
# 前言 在 深入浅出 JVM GC(1) 中,限于上篇文章的篇幅,我们留下了一个问题 : 如何回收? 这篇文章将重点讲述这个问题. 在上篇文章中,我们也列出了一些大纲,今天我们就按照那个大纲来逐个讲 ...
- 谁说深入浅出虚拟机难?现在我让他通俗易懂(JVM)
1:什么是JVM大家可以想想,JVM 是什么?JVM是用来干什么的?在这里我列出了三个概念,第一个是JVM,第二个是JDK,第三个是JRE.相信大家对这三个不会很陌生,相信你们都用过,但是,你们对这三 ...
- 阿里架构师带你深入浅出jvm
本文跟大家聊聊JVM的内部结构,从组件中的多线程处理,JVM系统线程,局部变量数组等方面进行解析 JVM JVM = 类加载器(classloader) + 执行引擎(execution engine ...
- 深入浅出 JVM GC(4)常用 GC 参数介绍
# 前言 从前面的3篇文章中,我们分析了5个垃圾收集器,还有一些 GC 的算法,那么,在 GC 调优中,我们肯定会先判断哪里出现的问题,然后再根据出现的问题进行调优,而调优的手段就是 JVM 提供给我 ...
- 深入浅出 JVM ClassLoader
# 前言 在 JVM 综述里面,我们说,JVM 做了三件事情,Java 程序的内存管理, Java Class 二进制字节流的加载(ClassLoader),Java 程序的执行(执行引擎).我们也说 ...
- 深入浅出 JVM GC(1)
# 前言 初级 Java 程序员步入中级程序员的有一个无法绕过的阶段------GC(Garbage Collection).作为 Java 程序员,说实话,很幸福,不用像 C 程序员那样,时刻关心着 ...
- 深入浅出JVM
这篇文章简要解析了JVM的内部结构.下面这幅图展示了一个典型的JVM(符合JVM Specification Java SE 7 Edition)所具备的关键内部组件. 上图展示的所有这些组件都将在下 ...
随机推荐
- [LintCode] O(1)检测2的幂次
class Solution { public: /* * @param n: An integer * @return: True or false */ bool checkPowerOf2(in ...
- CodeForeces 665C Simple Strings
C. Simple Strings time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...
- 6.javaScript中的二维数组
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- Python SQLAlchemy基本操作和常用技巧(包含大量实例,非常好)
https://www.jb51.net/article/49789.htm 首先说下,由于最新的 0.8 版还是开发版本,因此我使用的是 0.79 版,API 也许会有些不同.因为我是搭配 MySQ ...
- python - 常用的小方法
常用的小方法: bin() oct() hex() chr() ord() dir() id() len() int() str() type() help() range(10) / rang ...
- awesome-modern-cpp
Awesome Modern C++ A collection of resources on modern C++. The goal is to collect a list of resouce ...
- Redis与Memcached的比较(转)
原文:http://blog.nosqlfan.com/html/3729.html 这两年Redis火得可以,Redis也常常被当作Memcached的挑战者被提到桌面上来.关于Redis与Memc ...
- C++设计模式 -- 解析和实现
原文地址 http://c.chinaitlab.com/special/sjms/Index.html#a 导航目录 ※ 设计模式解析和实现之一-Factory模式 ※ 设计模式解析和实现之八-C ...
- Android 屏幕切换动画
public void overridePendingTransition (int enterAnim, int exitAnim) Call immediately after one of th ...
- 聚合的安全类导航、专业的安全知识学习平台——By Me:)
以“基于对抗的安全研发”为初衷,让大家在工作中始终有安全意识.安全思维和安全习惯,几年前自己搭建了面向公司内部全员的安全晨报.现在站在“用户“的角度回头看看,觉得科目设计等很多方面都还有很多的不足: ...