JVM内存管理:深入垃圾收集器与内存分配策略
Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来.
引用计数算法(Reference Counting)
最初的想法,也是很多教科书判断对象是否存活的算法是这样的:给对象中添加一个引用计数器,当有一个地方引用它,计数器加1,当引用失效,计数器减1,任何时刻计数器为0的对象就是不可能再被使用的.
根搜索算法(GC Roots Tracing)
在实际生产的语言中(Java、C#、甚至包括前面提到的Lisp),都是使用根搜索算法判定对象是否存活.算法基本思路就是通过一系列的称为"GC Roots"的点作为起始进行向下搜索,当一个对象到GC Roots没有任何引用链(Reference Chain)相连,则证明此对象是不可用的.在Java语言中,GC Roots包括:
①在VM栈(帧中的本地变量)中的引用
生存还是死亡?
大家在进行程序系统维护的时候是否因为java编程的内存管理问题而无法快速解决导致系统出错呢?下面我们就一起来了解和学习一下,关于java编程内存管理都有哪些知识点.
程序计数器(了解)程序计数器,可以看做是当前线程所执行的字节码的行号指示器.
在虚拟机的概念模型里,字节码解释器工作就是通过改变程序计数器的值来选择下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都要依赖这个计数器来完成.
Java虚拟机栈(了解)Java虚拟机栈也是线程私有的,它的生命周期与线程相同.
虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链表、方法出口信息等.
每一个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程.
局部变量表中存放了编译器可知的各种基本数据类型(boolean、byte、char、short、int、float、long、double)、对象引用和returnAddress类型(指向了一条字节码指令的地址).
如果扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常.
本地方法栈(了解)本地方法栈与虚拟机的作用相似,不同之处在于虚拟机栈为虚拟机执行的Java方法服务,而本地方法栈则为虚拟机使用到的Native方法服务.
有的虚拟机直接把本地方法栈和虚拟机栈合二为一.
会抛出stackOverflowError和OutOfMemoryError异常.
Java堆堆内存用来存放由new创建的对象实例和数组.
(重点)Java堆是所有线程共享的一块内存区域,在虚拟机启动时创建,此内存区域的目的就是存放对象实例.
Java堆是垃圾收集器管理的主要区域.
java课程培训机构发现由于现在收集器基本采用分代回收算法,所以Java堆还可细分为:新生代和老年代.
从内存分配的角度来看,线程共享的Java堆中可能划分出多个线程私有的分配缓冲区(TLAB).
从理论上来讲java做的系统并不比其他语言开发出来的系统更占用内存,那么为什么却有这么N多理由来证明它确实占内存呢?两个字,陋习.
(1)别用newBoolean().
Boolean类实际上只要两个实例就够了,一个true的实例,一个false的实例.
相信如果Java规范直接把Boolean的构造函数规定成private,就再也不会出现这种情况了.
这样如果我们使用Integer.valueOf代替newInteger的话也将大大降低内存的占用.
如果您的系统要在不同的SDK(比如IBMSDK)中使用的话,那么可以自己做了工具类封装一下,比如IntegerUtils.valueOf(),这样就可以在任何SDK中都可以使用这种特性.
这个我就不多讲了,因为已经被人讲过N次了.
我只想将一个不是笑话的笑话,我在看国内某"著名"java开发的WEB系统的源码中,竟然发现其中大量的使用字符串相加,一个拼装SQL语句的方法中竟然最多构造了将近100个string实例.
比如java课程认为使用HashMap缓存一些物料信息、人员信息等基础资料,这在提高系统速度的同时也加大了系统的内存占用,特别是当缓存的资料比较多的时候.
其实我们可以使用
Java的内存分配有三种,
①.、静态存储区:内存在程序编译时就分配好了,比如静态变量;
Java自有垃圾回收机制,所以Java编程不需要考虑回收问题.只要不是数组越界类似的问题,或者大规模的计算(超出计算机内存,导致内存溢出),那就没问题.
晕, 你确定你是用Java,
OK,不管Java还是C#
① 定义你的map
HashMapString, String map = new HashMapString, String();
map.put("userid", "userMessage");
....
if(map.size()100){
//map.remove(arg0)
}
更高级内容:
如果对map中的cache内容有过访问,给该内容的权重+1,每次删除的时候先将权重由小至大删除. 这就是命中率缓存,一般缓存都是按这种算法做的,只是具体算法有改进
以上就是土嘎嘎小编为大家整理的java内存管理代码优化相关主题介绍,如果您觉得小编更新的文章只要能对粉丝们有用,就是我们最大的鼓励和动力,不要忘记讲本站分享给您身边的朋友哦!!