JVM
五山口老法师
腾讯后台开发工程师
展开
-
01.几张图轻松理解String.intern()
当调用 intern() 方法时,编译器会将字符串添加到方法区的运行常量池中(stringTable维护),并返回指向该常量的引用。在翻《深入理解Java虚拟机》的书时,又看到了2-7的 String.intern()返回引用的测试。其实要搞明白String.intern(),我总结了下面几条规则:一、new String都是在堆上创建字符串对象。当调用 intern() 方法时,编译器会...原创 2018-11-27 12:20:55 · 926 阅读 · 0 评论 -
JVM:堆与栈的比较
堆(heap)与栈(stack) 堆和栈是程序运行的关键,很有必要它他们的关系说清楚。 在java中,Main函数就是栈的起始点,也是程序的起始点。程序要运行总是有一个起点的(程序执行的入口)。概括: 1 栈是运行时的单位 , 而堆是存储的单元。 2 栈解决程序的运行问题,即程序如何执行,或者说如何处理数据, 堆解决的是数据存储的问题,即数据...原创 2018-12-17 12:02:14 · 133 阅读 · 0 评论 -
JVM: G1和CMS的区别
CMS:以获取最短回收停顿时间为目标的收集器,基于并发“标记清理”实现有人会好奇为什么标记清理算法会产生内存碎片!但是CMS仍采用这种算法呢?答案是:因为CMS作为第一款实现用户线程和收集线程并发执行的收集器!当时的设计理念是减少停顿时间,最好是能并发执行!但是问题来了,如要用户线程也在执行,那么就不能轻易的改变堆中对象的内存地址!不然会导致用户线程无法定位引用对象,从而无法正常运行!而标...原创 2018-12-17 12:24:12 · 15876 阅读 · 7 评论 -
JVM:常用调优命令
Jvm堆内存的划分结构和优化,垃圾回收详解(详细解答篇)调试参数列表:参数及其默认值 描述 -XX:-CITime 打印消耗在JIT编译的时间 -XX:ErrorFile=./hs_err_pid<pid>.log 保存错误日志或者数据到文件中 -XX:-ExtendedDTraceProbes 开启solaris特有的dtrace探针 ...原创 2018-12-17 14:52:07 · 227 阅读 · 0 评论 -
JVM:jstack
jstack: stack trace for java用途:用于生成虚拟机当前时刻的线程快照(何为线程快照?就是指当前虚拟机中每一条线程正在执行的方法堆栈的集合)(为何要生成线程快照?为了定位线程出现长时间停顿的原因。)什么可以导致线程出现长时间的停顿?1)线程间死锁2)死循环3)请求外部资源导致长时间的等待应用场景:线程出现了长时间的停顿,就可以使...原创 2019-01-11 11:20:50 · 162 阅读 · 0 评论 -
JVM:堆中对象的创建?定位?可达性?
对象的创建指针碰撞:若是堆中的内存是绝对规整的,所有用过的内存放在一边,空闲的放在另一边,中间放着一个指针作为分界点的指示器,那所分配内存就仅仅是把那个指针向空闲空间那边挪动一段与对象大小相等的距离。指针碰撞要求堆中所采用的GC搜集器是带有“压缩整理”功能的!空闲列表:与指针碰撞相反,堆的内存空间是无序的,已使用内存和空闲内存交错,那便要使用一个空闲列表来记录堆中空闲内存的情况!根...原创 2019-02-18 23:38:38 · 288 阅读 · 0 评论 -
JVM:JVM内存划分、主内存、工作内存
java内存模型中的主内存只是JVM内存的一部分。每条线程拥有自己的工作内存。线程的工作内存中保存了该线程使用到的变量的主内存中的副本拷贝。java内存模型中的主内存、工作内存与之前JVM内存分布不是一个层次上的内存划分,这两者基本上是没有关系的。如果非要勉强对应,那从变量、主内存、工作内存的定义来看,主内存主要是对应于Java堆中的对象实例部分。工作内存则对应于虚拟机栈中的部分区域。...原创 2019-02-18 23:14:56 · 936 阅读 · 0 评论 -
JVM:-Xmx和-Xms应该维持什么样的比例?
-Xmx和-Xms应该维持什么样的比例?首先并不是虚拟机内存越大就越好,大概原因是因为:内存越大,JVM 进行 Full GC 所需的时间越久,由于 Full GC 时 stop whole world 特性,如果是用于响应HTTP 请求的服务器,这个时候就表现为停止响应,对于需要低延迟的应用来说,这是不可接受的。对于需要高吞吐量的应用来说,可以不在乎这种停顿,比如一些后台的应用之类的,那么内...原创 2019-02-19 16:01:04 · 4108 阅读 · 0 评论 -
JVM:7种垃圾回收器总结
这里讨论的收集器基于JDK1.7Update 14之后的HotSpot虚拟机,这个虚拟机包含的所有收集器如下图3-5所示: 上图展示了7种作用于不同分代的收集器,如果两个收集器之间存在连线,就说明它们可以搭配使用。所谓垃圾收集器在准确完整回收垃圾对象内存的基础上,所追求的目标是1)缩短Stop-The-World 的停顿时间2)尽可能使得垃圾收集线程和用户线程同时并发执行!!!...原创 2019-02-19 20:23:38 · 258 阅读 · 0 评论 -
JVM:四种引用总结
在JVM的GC中,我们使用引用计数器算法和可达性分析算法来确定一个对象是否gg了!这里都提到了引用!什么是引用?其实引用就是一个内存地址,它保存着另一个对象在内存中的起始地址!由于引用只有 被引用、没有被引用 两种状态!那么有一类现象:内存空间足够的时候,我们希望引用的对象能够保存,内存紧张的时候,可以抛弃这些对象!这个怎么搞????(软引用)因此扩充引用概念!将引用分...原创 2019-02-19 20:55:41 · 193 阅读 · 0 评论 -
JVM:gc什么时候开始?System.gc()能保证gc一定发生吗?
gc什么时候开始?“你能不能谈谈,java GC是在什么时候,对什么东西,做了什么事情?”在什么时候:1.新生代有一个Eden区和两个survivor区,首先将对象放入Eden区,如果空间不足就向其中的一个survivor区上放,如果仍然放不下就会引发一次发生在新生代的minor GC,将存活的对象放入另一个survivor区中,然后清空Eden和之前的那个survivor区的内存。在...原创 2018-12-17 11:39:39 · 5784 阅读 · 3 评论 -
JVM:永久代 以及jdk1.8为什么将其移除?
永久代在JDK8之前的HotSpot实现中,类的元数据如方法数据、方法信息(字节码,栈和变量大小)、运行时常量池、已确定的符号引用和虚方法表等被保存在永久代中,32位默认永久代的大小为64M,64位默认为85M,可以通过参数-XX:MaxPermSize进行设置,一旦类的元数据超过了永久代大小,就会抛出OOM异常。虚拟机团队在JDK8的HotSpot中,把永久代从Java堆中移除了,并把类...原创 2018-12-17 11:15:49 · 4135 阅读 · 4 评论 -
JVM:方法区可以GC吗?
方法区和堆一样,都是线程共享的内存区域,被用于存储已被虚拟机加载的类信息(字段等)、即时编译后的代码(方法字节码)、静态变量和常量等数据。根据Java虚拟机规范的规定,方法区无法满足内存分配需求时,也会抛出OutOfMemoryError异常,虽然规范规定虚拟机可以不实现垃圾收集,因为和堆的垃圾回收效率相比,方法区的回收效率实在太低,但是此部分内存区域也是可以被回收的。方法区的垃圾回收主要...原创 2018-12-15 21:11:32 · 5400 阅读 · 2 评论 -
02.字符串常量池 ? class常量池? 运行时常量池?
java对象创建流程:简介:这几天在看Java虚拟机方面的知识时,看到了有几种不同常量池的说法,然后我就去CSDN、博客园等上找资料,里面说的内容真是百花齐放,各自争艳,因此,我好好整理了一下,将我自认为对的理解写下来与大家共同探讨:在Java的内存分配中,总共3种常量池:1.字符串常量池(String Constant Pool):1.1:字符串常量池在Java内存区域的...原创 2018-11-27 12:23:38 · 144 阅读 · 0 评论 -
03.native方法(JNI)
native方法其实就是我们本地的方法 当我们java代码无法实现,可以使用c/c++实现。然后java调用本地的c/c++接口。http://www.cnblogs.com/HDK2016/p/7226840.html?utm_source=itdadao&utm_medium=referral...原创 2018-11-27 12:24:39 · 132 阅读 · 0 评论 -
JVM:GC日志解读
深入理解Java虚拟机 [JVM]Java内存区域与垃圾收集 - 思维导图 [JVM]类加载机制 - 思维导图 [JVM]OOM实例分析 [JVM]理解Class文件(1):手动解析常量池 [JVM]理解GC日志 [JVM]理解Class文件(2) 1. 输出GC日志通过阅读GC日志,我们可以了解Java虚拟机内存分配与回收策略。先来看一个简单的示例,通过设置...原创 2018-11-30 22:40:18 · 233 阅读 · 0 评论 -
04.Java 堆内存 新生代 老年代?
Java 中的堆是 JVM 所管理的最大的一块内存空间,主要用于存放各种类的实例对象。在 Java 中,堆被划分成两个不同的区域:新生代 ( Young )、老年代 ( Old )。新生代 ( Young ) 又被划分为三个区域:Eden、From Survivor、To Survivor。这样划分的目的是为了使 JVM 能够更好的管理堆内存中的对象,包括内存的分配以及回收。堆的内存模型大致...原创 2018-11-28 12:22:56 · 248 阅读 · 0 评论 -
JVM:类加载机制之类加载器
JVM设计者把类加载阶段中的“通过'类全名'来获取定义此类的二进制字节流”这个动作放到Java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类。实现这个动作的代码模块称为“类加载器”。 1.类与类加载器对于任何一个类,都需要由加载它的类加载器和这个类来确立其在JVM中的唯一性。也就是说,两个类来源于同一个Class文件,并且被同一个类加载器加载,这两个类才相等。2.双亲委派...原创 2018-12-07 16:44:23 · 238 阅读 · 0 评论 -
JVM:类加载机制之类加载过程
类加载机制概念 Java虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、准备、解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的加载机制。*Class文件由类装载器装载后,在JVM中将形成一份描述Class结构的元信息对象,通过该元信息对象可以获知Class的结构信息:如构造函数,属性和方法等,Java允许用户借由这个Class相关的元信息...原创 2018-12-07 16:46:11 · 159 阅读 · 0 评论 -
JVM:内存分配与回收策略?Full GC 的触发条件?StopTheWorld ?
内存分配与回收策略Minor GC 和 Full GC Minor GC:发生在新生代上,因为新生代对象存活时间很短,因此 Minor GC 会频繁执行,执行的速度一般也会比较快。 Full GC:发生在老年代上,老年代对象其存活时间长,因此 Full GC 很少执行,执行速度会比 Minor GC 慢很多。 内存分配与回收策略1. 对象优先在 Eden 分配大多数...原创 2018-12-15 09:47:03 · 1547 阅读 · 0 评论 -
jvm:类加载器与双亲委派模型
两个类相等需要类本身相等,并且使用同一个类加载器进行加载。这是因为每一个类加载器都拥有一个独立的类名称空间。这里的相等,包括类的 Class 对象的 equals() 方法、isAssignableFrom() 方法、isInstance() 方法的返回结果为 true,也包括使用 instanceof 关键字做对象所属关系判定结果为 true。类加载器分类从 Java 虚拟机的角度来...原创 2018-12-15 12:06:31 · 159 阅读 · 0 评论 -
JVM:内存划分总结
总结1、所有线程共享的内存数据区:方法区,堆。而虚拟机栈,本地方法栈和程序计数器都是线程私有的。2、存放于栈中的东西如下: 2.1 每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(不是对象)。对象都存放在堆区中。2.2 每个栈中的数据(基础数据类型和对象引用)都是私有的,其他栈不能访问。 2.3 方法的形式参数,方法调用完后从栈空间回收 2.4 引用对...原创 2018-12-15 12:19:11 · 155 阅读 · 0 评论 -
线程安全的强弱级别
线程安全:多个线程同时访问一个对象,不考虑在运行时环境下这些线程的调度和交替执行,无需进行额外的同步操作,或者在调用端也无需进行任何其它的协调操作,对于这个对象的调用行为都能够返回正确的结果,那么这个对象就是线程安全的。为什么会有线程安全的问题:根源在于多个线程之间存在共享数据访问的前提。线程安全等级:①不可变只要一个对象被正确的构建出来,它的状态就不能够发生改变的。若果共...原创 2019-08-04 10:42:41 · 451 阅读 · 0 评论