- 浏览: 1011338 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (826)
- 硬件 (8)
- 软件 (24)
- 软件工程 (34)
- JAVA (229)
- C/C++/C# (77)
- JavaScript (8)
- PHP (1)
- Ruby (3)
- MySQL (14)
- 数据库 (19)
- 心情记事 (12)
- 团队管理 (19)
- Hadoop (1)
- spring (22)
- mybatis(ibatis) (7)
- tomcat (16)
- velocity (0)
- 系统架构 (6)
- JMX (8)
- proxool (1)
- 开发工具 (16)
- python (10)
- JVM (27)
- servlet (5)
- JMS (26)
- ant (2)
- 设计模式 (5)
- 智力题 (2)
- 面试题收集 (1)
- 孙子兵法 (16)
- 测试 (1)
- 数据结构 (7)
- 算法 (22)
- Android (11)
- 汽车驾驶 (1)
- lucene (1)
- memcache (12)
- 技术架构 (7)
- OTP-Erlang (7)
- memcached (17)
- redis (20)
- 浏览器插件 (3)
- sqlite (3)
- Heritrix (9)
- Java线程 (1)
- scala (0)
- Mina (6)
- 汇编 (2)
- Netty (15)
- libevent (0)
- CentOS (12)
- mongod (5)
- mac os (0)
最新评论
-
kingasdfg:
你这里面存在一个错误添加多个任务 应该是这样的 /** * ...
Quartz的任务的临时启动和暂停和恢复【转】 -
kyzeng:
纠正一个错误,long型对应的符号是J,不是L。
Jni中C++和Java的参数传递 -
zhaohaolin:
抱歉,兄弟,只是留下作记录,方便学习,如果觉得资料不好,可以到 ...
netty的个人使用心得【转】 -
cccoooccooco:
谢谢!自己一直以为虚机得使用网线才可以与主机连接呢。。
主机网卡无网线连接与虚拟机通信 -
yuqilin001:
要转别人的东西,请转清楚点嘛,少了这么多类,误人子弟
netty的个人使用心得【转】
不同的JVM实现对堆结构的设计有所不同,这里先说说共性的,然后再比较classic vm和hotspot vm在gc方面的差异。
先
大致说说gc的过程,通常有两种情形会导致gc发生,一种是显式的System.gc()调用而java进程未禁止显示gc,第二种是隐式的,即内存管理
器(MM)在alloc内存时发生failure,MM进而作gc以便释放出空间用于分配(当然,假如gc后还是没有空间可满足分配数
值,OutOfMemory就发生了)。gc过程分3步走,第1步,mark阶段,标示出allocbits和markbits,allocbits
代表当前java
heap中存在的对象所占内存的bit映射,markbits代表所有reachable对象所占内存的bit映射,是allocbits的子集。这一
步,一般是要锁定java
heap的,但有些gc器能做到并发/并行mark(后面有解释)。第2步,sweep阶段,即将markbits和allocbits的补集所代表的内
存区域作回收,这也包括对class的回收,假如classgc未被禁用,而jvm确实找到了未被使用的class,那么除了java
heap中的Class对象被回收,method area里该class的method data也被释放。第3步,compact阶段(可选的,jvm会自行判断是否进行该步),整理碎片,两种技巧,一种是移动琐碎的对象区域,使之连续,一种是移动琐碎的free区域,也使之连续。
这步也必须要锁定java heap。compact时还要做一个工作,即将所移动的对象的原始引用值作同步更新。这时存在一个问题,假如某thread stack里的一个浮点数碰巧看起来像是一个对象引用值
(内存泄露也会因此情形而发生)
,那么jvm因为无法断定而放弃移动该对象,等待以后再移动(据称,hotspot vm对精确判定引用值的问题解决的较好)。
再
解释一下mark阶段,为了得到markbits,首先要收集root references,也就是java thread stacks refs,
jni global refs,thread moniters,interned strings,and soft/weak
refs等,它们是对象引用的源头,从root referent object顺藤摸瓜,即可把所有reachable
object标示出来。再解释一下bits映射,每一个bit代表每一个内存GRAIN(是分配的最小粒度),假设GRAIN是8
byte,那么对于64M的堆,需要额外的1M的bits来映射,这部分额外开支需要gc器向c
heap申请,当堆扩展和收缩时,markbits也要随之变动。mark阶段工作量比较大,因为要扫描和遍历,所以后期的jvm都采用多种新的方式如
concurrent(普通线程也参与mark)或parallel(多cpu有效)进行mark。
再说堆的扩张(Expansion)
和收缩(Shrinkage)。当内存不足时,gc清理一遍后还发现free空间不能满足分配的尺寸要求,那么它有两种手段继续推进,如果最大堆
(-Xmx)未达到,那么扩展堆,如果已达到,那么强制回收soft/weak
referents,如果此时还不能满足,那么OutOfMemory就发生了。而当经过一段运行时间后,jvm判断free区域较多(不同的jvm判定
依据有所不同),那么就会收缩java
heap。收缩的好处有两个,1是减轻OS的负担,2又减少了jvm内存管理器的维护成本。注意,不论再怎么收缩,也不可能小于最小堆(-Xms)。默认
的ms值和mx值各vm提供商有所不同,请参阅其文档。
个人认为主流的jvm主要有3种,sun classic, ibm
classsic,sun hotspot。sun
classsic用于1.3.0以前,之后sun的jvm都是hotspot。而ibm的jdk一直是classsic,不知其5.0的vm是否会采用
hotspot。sun的是主流无可置疑啦,为什么扯上ibm的呢,因为看过一个民间的性能评测结果,ibm
1.42vm比sun的1.42vm甚至略好。sun
classic使用间接句柄分配对象,所以堆分为两部分,一块放object,一块放handle。这个好处是compact方便得很,缺点也是很严重的
缺点,是对象访问不直接,要多一层指针转换,对性能大有影响。ibm classic的具体细节的资料比较缺乏,但根据其white
paper,似乎使用的是直接句柄(否则性能无法比sun的好),另外它将java heap划分成system
heap和一般heap,仅将jvm的系统class和对象分配到system heap里,它还支持并行和并发的gc。sun
hotspot使用直接句柄,似乎又采用了一些高级手段,做到了精确辨别,因此快而且回收准确,另外提供了多种的gc器,适用于不同场合。值得一提的是它
的代生gc器(Generational Copying
Collection),根据对象生命周期模型(小对象居多,生命周期短),使用类似stack的方式,将同一时期产生的对象放在同一容器
(nursery)中,这批对象基本上会同时消亡,这样,回收时可直接将
容器
释放,避免了繁琐的逐个对象释放的过程,因此可以减少gc的花费时间(duration)和频度(frequency),并且
容器
是现成的,所以分配时,寻找free空间很方便,所以提高了分配的效率。
本篇再加上前面的几篇,已经把JVM和Memory相关的主要机理和过程都已经覆盖了,下一篇主要是关于tuning和trouble shooting,请关注。
补:
再说一下内存泄露(memory leak),与c/c++的内存泄露的概念不同,java的memory
leak是指无用(unused)的对象因为仍然是reachable的,所以不能被gc,因而造成内存的被白白占用。造成memory
leak的原因是多样的,比如程序未及时给变量赋null,再比如上文提到的浮点数被碰巧当成对象引用,或者jni程序里声明的global
ref忘了做撤销。对于服务器程序来说,memory
leak的逐渐积累,只要运行时间足够,必然造成OutOfMemory。如何确定jvm是否有内存泄露呢,假使你没有监测工具也不要紧,打开-
verbose:gc开关,运行系统足够长的时间(约收集20到50次gc的数据),然后将verbosegc的信息作收集,察看java
heap的谷值(gc后java heap的大小,峰值则表示gc前java
heap的大小)是否有递增的倾向,如果倾向明显,那么很有可能是memory leak问题。
发表评论
-
A Collection of JVM Options
2011-06-24 12:59 1157A Collection of JVM Options ... -
java中堆(heap)和堆栈(stack)有什么区别
2011-05-10 14:29 893stack 和 heep 都是内存的一部分 stack 空间 ... -
JVM & Memory (5) final
2011-05-10 14:25 994先说tuning,gc有两个指标,一个是frequentcy( ... -
JVM & Memory (3) thread
2011-05-10 14:21 905以下继续探讨,说说jvm ... -
JVM & Memory (2) java.exe
2011-05-10 14:20 943上篇说到了关于java heap ... -
JVM & Memory (1) paging
2011-05-10 14:19 958近期看了一些有关JVM和内存的资料,为了避免遗忘,特在这里作一 ... -
JDK TOOLS
2011-05-10 14:15 812以下这几种工具(存在于 ... -
jvm日志分析工具应用
2011-05-10 14:14 2815涛涛学习笔记之gc日志分析工具 测试环境:xp+weblog ... -
JVM优化配置
2011-05-10 13:56 933OOM 这个缩写就是Java程 ... -
高手详细介绍JVM是什么?
2011-05-10 13:52 873首先这里澄清两个概念:JVM实例和JVM执行引擎实例,JVM实 ... -
JVM监控工具介绍
2011-03-22 14:25 891... -
正确认识java JVM与c/c++的执行效率
2011-03-22 10:43 1411认为Java 不能写JVM是完全错误的。JNode是一个用 ... -
Java虚拟机(JVM)参数配置说明
2011-03-22 10:26 985Java虚拟机(JVM)参数配置说明 ... -
解析 Java 类和对象的初始化过程
2011-03-21 23:40 908解析 Java 类和对象的初始化过程 由一个单态模式引出的问 ... -
JDK的概念、组成及JDK常用包
2011-03-18 22:09 1138JDK概述 JDK (Java Development ... -
安装JDK后JRE与JVM联系浅谈
2011-03-18 22:08 915安装JDK后JRE、JVM之间的 ... -
详细介绍什么是Java虚拟机
2011-03-18 22:07 840本文由浅入深,先从什么是Java虚拟机、Java虚拟机 ... -
认识Java虚拟机及其性能
2011-03-18 22:04 726Java虚拟机(Java virtual ... -
JVM GC调整优化过程全揭秘
2011-03-18 22:03 838JVM GC调整优化是以个极为复杂的过程,由于各个程序具备 ... -
Java虚拟机的研究与实现(图文)
2011-03-18 21:59 1032引言 Java 虚拟机本质是就是一个程序,当它在命令行 ...
相关推荐
垃圾收集的主要类型有四种,虽然在内容中没有具体提到这四种类型,但在JVM中常见的垃圾收集器包括Serial GC、Parallel GC、CMS(Concurrent Mark Sweep)GC和G1(Garbage-First)GC等。这些垃圾收集器有不同的特性,...
4. **GC调优的目标**:减少Full GC的频率,缩短其执行时间,以及降低STW(Stop-The-World)带来的应用暂停时间。 5. **JVM参数调整**:通过设置JVM参数可以影响GC行为,如`-Xms`和`-Xmx`控制堆内存大小,`-XX:...
《JVM性能调优——JVM内存整理及GC回收》是针对Java开发人员的重要主题,尤其是在大型企业级应用中,确保JVM(Java虚拟机)的高效运行是至关重要的。本资料深入探讨了如何通过调整JVM内存设置和优化垃圾回收机制来...
### JVM体系结构与GC调优 #### 一、JVM体系结构概述 Java虚拟机(JVM)是Java运行环境的基础部分,它为Java程序提供了一个独立于平台的执行环境。JVM的主要职责包括:加载Java类到内存、管理运行时数据区域、执行...
JVM(Java Virtual Machine)的垃圾收集器(GC,Garbage Collector)扮演着核心角色,负责自动管理应用程序的内存,防止内存泄漏和性能问题。MAT(Memory Analyzer Tool)是由Eclipse基金会提供的一个强大的分析工具...
4. **GC次数和时间**:监控GC的触发频率和每次GC所用的时间,有助于识别潜在的性能问题。 5. **内存池(Memory Pool)状态**:了解不同内存区域(如Eden、Survivor、Old等)的使用情况,有助于调整JVM参数以优化性能...
4. **堆(Heap)**:存放所有对象实例及数组,是Java应用中最大的一块内存区域,支持垃圾回收。 5. **方法区(Method Area)/运行时常量池(Runtime Constant Pool)**:存储类的信息,包括类名、方法信息、常量等...
《深入解析MemoryAnalyzer:JVM堆内存分析利器》 在Java开发中,内存管理是至关重要的环节,良好的内存管理能够优化应用性能,防止内存泄漏,提升系统稳定性。MemoryAnalyzer(MAT)是一款强大的JVM堆内存分析工具...
《深入理解MemoryAnalyzer:JVM内存分析利器》 在Java应用程序的开发和优化过程中,内存管理是一项至关重要的任务。MemoryAnalyzer(MAT)是一款强大的JVM内存分析工具,它能够帮助开发者深入洞察应用的内存占用...
5. **GC日志分析**:通过分析JVM产生的GC日志,可以了解垃圾回收的效率和内存使用情况,从而调整参数以优化性能。 6. **内存泄漏检测**:关注长期未被释放的对象,可能暗示存在内存泄漏问题。开发者可以通过工具如...
《JVM Full GC 之 MAT 工具分析实践》 在Java开发中,理解JVM内存管理和垃圾收集机制至关重要,因为这直接关系到应用程序的性能和稳定性。当遇到内存溢出(OutOfMemoryError)、系统异常或者性能下降等问题时,我们...
4. 监控GC日志:通过-XX:+PrintGC、-XX:+PrintGCDetails、-XX:+PrintGCDateStamps等参数,记录并分析垃圾收集行为。 5. 分析内存泄漏:利用内存分析工具,如MAT(Memory Analyzer Tool),对heap dump文件进行深度...
4. 调整Elasticsearch的配置:Elasticsearch本身也提供了一些与GC相关的配置选项,例如调整Elasticsearch节点的通信超时参数(discovery.zen.fd.ping_interval, discovery.zen.fd.ping_timeout, discovery.zen.fd....
内存溢出(Out Of Memory,OOM)是JVM运行过程中常见的问题,主要类型有堆溢出、栈溢出、方法区溢出等。通过分析日志和调整参数可以解决这些问题。 总结,JVM是Java编程的关键组成部分,理解其工作原理、内存模型和...
另外,内存转储分析工具如MAT(Memory Analyzer Tool)和JProfiler等第三方分析工具也可以用来诊断和分析JVM的性能问题。 对于调优的性能指标,通常考虑的有内存占用、启动时间、吞吐量、GC开销和GC暂停时间以及...
通过具体案例,如系统频繁FullGC、String.intern的使用等,可以更加深入理解JVM的运行机制和性能调优方法。 #### 结语 以上是对《JVM必知必会》中涉及的核心知识点的详细梳理。这些内容可以作为学习Java虚拟机的...
- 直接内存(Direct Memory)不是JVM内存的一部分,但通过NIO可以使用,不计入堆内存计算。 了解这些概念有助于优化Java应用性能,减少内存泄漏和提高程序效率。在实际开发中,理解JVM的工作原理对于解决内存问题...