JVM内存结构与GC
JVM内存模型总体架构图

程序计数器
多线程时,当线程数超过CPU数量或CPU内核数量,线程之间就要根据时间片轮询抢夺CPU时间资源。因此每个线程有要有一个独立的程序计数器,记录下一条要运行的指令。线程私有的内存区域。如果执行的是JAVA方法,计数器记录正在执行的java字节码地址,如果执行的是native方法,则计数器为空。
虚拟机栈(栈内存)
线程私有的,与线程在同一时间创建。管理JAVA方法执行的内存模型。每个方法执行时都会创建一个桢栈来存储方法的的变量表、操作数栈、动态链接方法、返回值、返回地址等信息。栈的大小决定了方法调用的可达深度(递归多少层次,或嵌套调用多少层其他方法,-Xss参数可以设置虚拟机栈大小)。栈的大小可以是固定的,或者是动态扩展的。如果请求的栈深度大于最大可用深度,则抛出stackOverflowError;如果栈是可动态扩展的,但没有内存空间支持扩展,则抛出OutofMemoryError。
本地方法区
和虚拟机栈功能相似,但管理的不是JAVA方法,是本地方法,本地方法是用C实现的。
JAVA堆
线程共享的,存放所有对象实例和数组。垃圾回收的主要区域。可以分为新生代和老年代(tenured)。
新生代用于存放刚创建的对象以及年轻的对象,如果对象一直没有被回收,生存得足够长,老年对象就会被移入老年代。
新生代又可进一步细分为eden、survivorSpace0(s0,from space)、survivorSpace1(s1,to space)。刚创建的对象都放入eden,s0和s1都至少经过一次GC并幸存。如果幸存对象经过一定时间仍存在,则进入老年代(tenured)。

方法区(永久代)
线程共享的,用于存放被虚拟机加载的类的元数据信息:如常量、静态变量、即时编译器编译后的代码。也成为永久代。如果hotspot虚拟机确定一个类的定义信息不会被使用,也会将其回收。回收的基本条件至少有:所有该类的实例被回收,而且装载该类的ClassLoader被回收。方法区存储了下面两种类型的数据:
1.Class的节本信息
Package Name
Super class package name
Class or interface
Type modifiers
Super inferface package name
2.其它信息
The constant pool for the type
Field information
Method information
All class (static) variables declared
in the type, except constants
A reference to class ClassLoader
A reference to class Class
SUN设计的时候认为这个区域在JVM启动的时候就固定了,但他没有想到现在动态会用得这么广泛。而且这个区域有特殊的垃圾收回机制,现在的问题是动态加载类到这个区域后,gc根本没办法回收!
现在开发中最常见的错误莫过于Permgen Space!
解决办法:
1,把不必要的 jar 文件清理出 lib;
2,不要频繁地进行 reload;
3,增加 PermGen Space 内存区域,默认是 64MB,可以采用 -XX:MaxPermSize 这个 JVM 参数改这块区域改大一些,这个参数详见:
http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html
如果用的是 Tomcat 的话,可以在 catalina.bat 开始处增加一行 set JAVA_OPTS=-XX:MaxPermSize=128m
垃圾回收算法
复制算法(copying)
将内存分成两块,每次只使用其中一块,垃圾回收时,将标记的对象拷贝到另外一块中,然后完全清除原来使用的那块内存。复制后的空间是连续的。复制算法适用于新生代,因为垃圾对象多于存活对象,复制算法更高效。在新生代串行垃圾回收算法中,将eden中标记存活的对象拷贝未使用的s1中,s0中的年轻对象也进入s1,如果s1空间已满,则进入老年代;这样交替使用s0和s1。这种改进的复制算法,既保证了空间的连续性,有避免了大量的内存空间浪费。
标记-压缩算法(Mark-compact)
适合用于老年代的算法(存活对象多于垃圾对象)。
标记后不复制,而是将存活对象压缩到内存的一端,然后清理边界外的所有对象。
注意:
1.增加Heap的大小虽然会降低GC的频率,但也增加了每次GC的时间。并且GC运行时,所有的用户线程将暂停,也就是GC期间,Java应用程序不做任何工作
JVM参数:
-XX:+PrintGCDetails 打印垃圾回收信息
-Xms 为Heap区域的初始值,线上环境需要与-Xmx设置为一致,否则capacity的值会来回飘动
-Xmx 为Heap区域的最大值
-Xss(或-ss) 线程栈大小(指一个线程的native空间)1.5以后是1M的默认大小
-XX:PermSize与-XX:MaxPermSize 方法区(永久代)的初始大小和最大值(但不是本地方法区)
-XX:NewRatio 老年代与新生代比率
-XX:SurvivorRatio Eden与Survivor的占用比例。例如8表示,一个survivor区占用 1/8 的Eden内存,即1/10的新生代内存,为什么不是1/9?因为我们的新生代有2个survivor,即S1和S22。所以survivor总共是占用新生代内存的 2/10,Eden与新生代的占比则为 8/10。
-XX:MaxHeapFreeRatio GC后,如果发现空闲堆内存占到整个预估的比例小于这个值,则减小堆空间。
-XX:MinHeapFreeRatio GC后,如果发现空闲堆内存占到整个预估的比例大于这个值,则增大堆空间。
-XX:NewSize 新生代大小
Jstat用法
http://my.oschina.net/skyline520/blog/304805
打出进程堆栈信息
jmap -dump:format=b,file=2.dump pid
查看java运行系统内部信息
先用top -H -p pid 找到进程下cpu最高的线程 比如是4571 (16进账是11DB)
然后用jstack pid > jstack.log
然后在log文件中查看11DB的信息
本文转载整理至:
http://blog.csdn.net/kingofworld/article/details/17718587
http://www.cnblogs.com/dingyingsi/p/3760447.html
http://blog.csdn.net/ji13921602232/article/details/51159142
http://blog.csdn.net/doc_sgl/article/details/46594975
http://my.oschina.net/skyline520/blog/304805
JVM内存结构与GC的更多相关文章
- 管中窥豹——从对象的生命周期梳理JVM内存结构、GC调优、类加载、AOP编程及性能监控
如题,本文的宗旨既是透过对象的生命周期,来梳理JVM内存结构及GC相关知识,并辅以AOP及双亲委派机制原理,学习不仅仅是海绵式的吸收学习,还需要自己去分析why,加深对技术的理解和认知,祝大家早日走上 ...
- 面试重灾区——JVM内存结构和GC
JVM介绍 1. JVM的体系架构(内存模型) 绿色的为线程私有,橘色的为线程共有 2. 类加载器 负责将.class文件加载到内存中,并且将该文件中的数据结构转换为方法区中的数据结构,生成一个Cla ...
- 一文搞懂JVM内存结构+GC
一.jvm是干什么的? 大家都知道java是跨平台语言,一次编译可以在不同操作系统上运行,怎么做到的呢,看下图: javac把写的源代码(java文件),编译成字节码(class文件),字节码部署到l ...
- jvm系列(二):JVM内存结构
JVM内存结构 所有的Java开发人员可能会遇到这样的困惑?我该为堆内存设置多大空间呢?OutOfMemoryError的异常到底涉及到运行时数据的哪块区域?该怎么解决呢?其实如果你经常解决服务器性能 ...
- JVM内存结构之三--持久代
本文会介绍一些JVM内存结构的基本概念,然后很快会讲到持久代,来看下Java SE 8发布后它究竟到哪去了. 基础知识 JVM只不过是运行在你系统上的另一个进程而已,这一切的魔法始于一个java命令. ...
- JVM内存结构
前言 在Java语言开发过程中,out of memory错误是很常见的一种错误.对于JVM的内存结构有更深入的了解,更更好的帮我们排查此类问题,有效的避免此类问题发生.在JAVA 8中内存结构有进行 ...
- JVM内存结构,运行机制
三月十号,白天出去有事情出去了一天,晚上刚到食堂就接到阿里电话, 紧张到不行,很多基础的问题都不知道从哪里说了orz: 其中关于JVM内存结构,运行机制,自己笔记里面有总结的,可当天还是一下子说不出来 ...
- jvm系列二、JVM内存结构
原文链接:http://www.cnblogs.com/ityouknow/p/5610232.html 所有的Java开发人员可能会遇到这样的困惑?我该为堆内存设置多大空间呢?OutOfMemory ...
- JVM内存结构之堆、栈、方法区以及直接内存、堆和栈区别
JVM内存结构之堆.栈.方法区以及直接内存.堆和栈区别 一. 理解JVM中堆与栈以及方法区 堆(heap):FIFO(队列优先,先进先出):二级缓存:*JVM中只有一个堆区被所有线程所共享:对象和数 ...
随机推荐
- 25个最常用的iptables策略
1.清空存在的策略当你开始创建新的策略,你可能想清除所有的默认策略,和存在的策略,可以这么做:iptables -F 或者iptables --flush2,设置默认策略默认链策略是ACCEPT,改 ...
- Distribute Cached 使用
在Kettle中说到Pentaho的MapReduce要用到它,就查了一下关于它的资料,以下是从官方查到的内容,记录一下. DistributedCache: 一些比较小的需要共享的文件或者jar包, ...
- Django添加防跨站请求伪造中间件
第一步: 在全局设置中打开此中间件: MIDDLEWARE_CLASSES = [ ... 'django.middleware.csrf.CsrfViewMiddleware', ... ] ...
- jQuery(五):文本操作
text()可以获取或设置元素的文本内容.例如: 示例: <!DOCTYPE html> <html lang="en"> <head> < ...
- 关于qt QWebKit/QWebview 使用心得
当前项目为c/s客户端,采用qt4.8.7,需要使用仪表盘.折线图.柱状图等,曾经使用过qwt和自定义的图形控件,但是都不尽如人意.最近发现ECharts控件不错.为此就要在qt端使用web的技术.为 ...
- ssh : how to add "hostkey" to “know_hosts”
有时后端daemon或者脚本在执行ssh连接时,会遇到以下提示: The authenticity of host 'git.sws.com (10.42.1.88)' can't be establ ...
- win8.1系统如何激活
若是系统是win8.1或者win8系统,可能由于产品过期或者采用的系统不是正版的话,会出现windows 未激活的状态,想要激活需下载一个win8/win8.1系统 激活工具. http://www. ...
- python with 语句妙用
class aa(): def bb(self): print("hhhh") return "hello world" def __enter__(self) ...
- Sql Server性能优化辅助指标 - SET STATISTICS TIME ON和SET STATISTICS IO ON
1.前言 对于优化SQL语句或存储过程,以前主要是用如下语句来判断具体执行时间,但是SQL环境是复杂多变的,下面语句并不能精准判断性能是否提高:如果需要精确知道CPU.IO等信息,就无能为力了. ), ...
- Zookeeper系统设计的优点
转自:Zookeeper系统设计的优点.http://webcache.googleusercontent.com/search?q=cache:s6fr40t_5ncJ:www.chaozh.com ...