关于jvm的相关知识
一、堆内存和栈内存
1、jvm中的栈内存主要存储的是基本类型的变量和对象的引用
2、jvm中的堆内存主要存储的是用new来创建的对象和数组,可变长字符串(StringBuilder和StringBuffered)都是存储在堆内存的
使用堆的优点是动态分配存储空间,更灵活,但缺点是由于要动态分配内存,所以存储速度较慢;而使用栈速度就比较快,也可以实现数据的共享,但缺点是栈中的数据大小和生存期是必须确定的,缺乏灵活性
3、静态存储分配是存储静态变量和静态代码块的
二、jvm的认识
jvm即java虚拟机,它屏蔽了与具体操作系统平台相关的信息,使java程序只生成在java虚拟机上运行的目标代码(字节码),这样就可以实现跨平台运行;
它的原理是:java源文件经过java编译器编译成字节码程序,通过jvm将每一条指令翻译成不同平台的机器码,通过特定的平台运行;
jvm的内存区域主要分为:方法区,jvm栈,堆,本地方法栈,程序计数器
程序计数器:用于记录当前执行到的那个指令,这是唯一一个没有oom情况的区域;
jvm栈:线程私有,每个线程创建的同时都会创建jvm栈,它存放的是当前线程中局部的基本变量,部分返回结果以及stack frame,还有对象的引用地址;
堆:线程共享,用来存储一些对象以及数组;既然共享,就需要加锁,所以导致开销大;
方法区:这个方法区对应的是持久代,它存放的是类的信息(名称、修饰符等等)、类中的静态变量、类中用final定义的常量等等;
本地方法栈:用来支持native方法的执行,用来储存每个native方法的调用状态;
java垃圾回收主要是针对堆和方法区:堆分为新生代和老年代,一般刚刚new出来的对象都会被放入到新生代;而新生代又分为Eden区和两个Survivor区;
垃圾回收的机制就是:首先判断出哪些对象是垃圾,即不再被使用,然后利用相应的算法(标记-清除算法、复制算法、标记-整理算法、分代收集算法)对垃圾进行回收;
1、标记-清除算法:
分两个阶段,标记阶段和清除阶段,首先标记出需要被回收的对象,然后再回收标记对象所占有的空间;
它的实现比较简单,但是缺点就是容易产生内存碎片,导致后续需要为大对象分配空间时找不到足够的内存而提前触发一次新的垃圾回收动作;
2、复制算法:
复制算法为了解决标记-清除算法的缺点,它将内存按容量划分成大小相等的两块区域,每次只使用其中的一块;当一块用完了之后,就将还存活着的对象复制到另外一块区域,然后再把使用过的那一块区域清理掉,这样就不容易出现碎片;
解决了内存碎片的问题,但是缺点是将使用的内存减少到了原来的一半,并且复制的效率跟存活下来的对象数量有关,当数量很大时,效率大大降低;
3、标记-整理算法
为了解决复制算法的缺陷,标记-整理算法诞生,标记阶段也跟标记-清除算法一样,先把需要回收的对象标记出来,但是它不是直接回收,而是将存活的对象都向另一边移动,然后清理掉边界以外的内存;
4、分代收集算法
这是目前用的最多的一个算法,它的核心思想是根据对象的存活周期将内存划分为若干个不同的区域,一般情况下将堆区划分为新生代和老年代,老年代的特点就是每次垃圾回收时需要回收的对象比较少,而新生代的就比较多,所以采取不一样的算法;
目前新生代大部分采用的是复制算法,但实际上并不是按照1:1的比例来划分新生代的空间的,一般来说是将新生代划分为一块较大的Eden空间和两块较小的Survivor空间,每次使用Eden空间和其中的一块Survivor空间,当进行回收时,将Eden和Survivor中还存活的对象复制到另一块Survivor空间中,然后清理掉Eden和刚才使用过的Survivor空间。
而由于老年代的特点是每次回收都只回收少量对象,一般使用的是标记-整理(Mark-Compact)算法。
注意,在堆区之外还有一个代就是永久代(Permanet Generation),它用来存储class类、常量、方法描述等。对永久代的回收主要回收两部分内容:废弃常量和无用的类。
那么我们怎么确定什么对象是“垃圾”呢?
方法一、引用计数法:
在java中是通过引用来和对象进行关联的,也就是说如果要操作对象,必须通过引用来进行。那么很显然一个简单的办法就是通过引用计数来判断一个对象是否可以被回收。不失一般性,如果一个对象没有任何引用与之关联,则说明该对象基本不太可能在其他地方被使用到,那么这个对象就成为可被回收的对象了。这种方式成为引用计数法。
优点:实现简单,效率高
缺点:无法解决循环引用的问题
方法二、可达性分析法:
该方法的基本思想是通过一系列的“GC Roots”对象作为起点进行搜索,如果在“GC Roots”和一个对象之间没有可达路径,则称该对象是不可达的,不过要注意的是被判定为不可达的对象不一定就会成为可回收对象。被判定为不可达的对象要成为可回收对象必须至少经历两次标记过程,如果在这两次标记过程中仍然没有逃脱成为可回收对象的可能性,则基本上就真的成为可回收对象了。
哪些对象可以成为GC Roots呢?
1.jvm栈(栈帧中的本地变量表)中引用的对象。
2.方法区中类静态属性引用的对象。
3.方法区中常量引用的对象
4.本地方法栈中JNI(即一般说的Native方法)引用的对象。
对于程序员来说,我们也可以通过一些方法来减少GC开销:
1、不要显示地调用System.gc()方法
2、尽量减少临时对象的使用
3、对象不用的时候显示地设置为null
4、尽量使用StringBuilder来代替String累加字符串
5、能用基本类型的变量(int long),就不要用对象(Integer、Long)
6、尽量少使用静态对象变量
关于jvm的相关知识的更多相关文章
- JVM的相关知识整理和学习--(转载)
JVM是虚拟机,也是一种规范,他遵循着冯·诺依曼体系结构的设计原理.冯·诺依曼体系结构中,指出计算机处理的数据和指令都是二进制数,采用存储程序方式不加区分的存储在同一个存储器里,并且顺序执行,指令由操 ...
- JVM相关知识
Java虚拟机学习分享最近主要在学习JVM相关知识,-知识主要来源<深入理解JAVA虚拟机>,深有感触,结合自己的理解,整理出一些经验,由于篇幅较长,就把链接帖出来,希望对大家有所帮助: ...
- 一张思维导图带你梳理HashMap相关知识
HashMap可以说是java中最常见也是最重要的key-value存储结构类,很多程序员可能经常用,但是不一定清楚这个类背后的数据结构和相关操作原理,为了复习HashMap相关的知识,今天花了一天的 ...
- 【Python五篇慢慢弹(5)】类的继承案例解析,python相关知识延伸
类的继承案例解析,python相关知识延伸 作者:白宁超 2016年10月10日22:36:57 摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下.官方给 ...
- 移动WEB像素相关知识
了解移动web像素的知识,主要是为了切图时心中有数.本文主要围绕一个问题:怎样根据设备厂商提供的屏幕尺寸和物理像素得到我们切图需要的逻辑像素?围绕这个问题以iphone5为例讲解涉及到的web像素相关 ...
- listener监听器的相关知识
从别人的博客上我学习了listener的相关知识现在分享给大家 1.概念: 监听器就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上 ...
- UIViewController相关知识
title: UIViewController 相关知识date: 2015-12-13 11:50categories: IOS tags: UIViewController 小小程序猿我的博客:h ...
- 【转】java NIO 相关知识
原文地址:http://www.iteye.com/magazines/132-Java-NIO Java NIO(New IO)是从Java 1.4版本开始引入的一个新的IO API,可以替代标准的 ...
- NSString使用stringWithFormat拼接的相关知识
NSString使用stringWithFormat拼接的相关知识 保留2位小数点 1 2 3 4 //.2代表小数点后面保留2位(2代表保留的数量) NSString *string = [NSSt ...
随机推荐
- C#_数据转换 实用方法
[String转Array]string str = "123asd456asd789";单字符: string[] a0 = str.Split('a');多字符: string ...
- Flex条件判断中注意事项
1:等于判断条件,一定注意写两个==等号, if (obj.ProcessType="Relation") 如果只写一个等号,编译不会报错,并且Flex会认为是赋值操作,并且该语句 ...
- 如何用bat批处理编译swf项目
平时用FB等IDE编译多模块的游戏项目时,除了添加移除模块的操作很繁琐外,编译速度也非常之慢.而用bat来编译swf项目,速度非常快,稳定. 在此分享自己工作用的bat,每次运行会重新编译主模块Gam ...
- 【android design】android常用设计资源
一.概述 大部分程序员擅长开发,但是对于设计却知之甚少.这直接导致,程序员在初期开发出来的应用(大多为兴趣或实用导向)中看不中用.因此,有必要搜集整合一些设计资源,这样既能减轻程序员在设计上所耗费的时 ...
- android-Activity(四大组件之一)
一.Activity理解 1.定义: 直译为活动,是Android定义四大应用组件之一,也是最重要的用的最多的: 用来提供一个能让用户操作并与之交互的界面 一个应用有多个界面也就是包含多个Activi ...
- 获取行间样式与在js中设置样式
!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/x ...
- ASPCMS标签教程
导航栏调用{aspcms:navlist type=0} <a href="[navlist:link]">[navlist:name]</a>{/a ...
- python操作Excel读写--使用xlrd和xlwt
一.安装xlrd模块 到python官网下载http://pypi.python.org/pypi/xlrd模块安装,前提是已经安装了python 环境. 进入到解压文件路径,输入 setup.py ...
- Bootstrap css栅格 + 网页中插入代码+css表格
设计达人 http://www.shejidaren.com/30-minimal-app-icons.html CSS栅格: <!DOCTYPE html> <html lang= ...
- SQLiteDatabase浅谈
(一).简介: Android通过 SQLite 数据库引擎来实现结构化数据的存储.在一个数据库应用程序中,任何类都可以通过名字对已经创建的数据库进行访问,但是在应用程序之外就不可以. SQLite ...