
java高级话题
文章平均质量分 76
aitangyong
成长最快、最好的方式就是交流和总结!
展开
-
System.gc()和-XX:+DisableExplicitGC启动参数,以及DirectByteBuffer的内存释放
我们知道java代码无法强制JVM何时进行垃圾回收,也就是说垃圾回收这个动作的触发,完全由JVM自己控制,它会挑选合适的时机回收堆内存中的无用java对象。代码中显示调用System.gc(),只是建议JVM进行垃圾回收,但是到底会不会执行垃圾回收是不确定的,可能会进行垃圾回收,也可能不会。什么时候才是合适的时机呢?一般来说是,系统比较空闲的时候(比如JVM中活动的线程很少的时候),还有就是内存不足,不得不进行垃圾回收。我们例子中的根本矛盾在于:堆内存由JVM自己管理,堆外内存必须要由我们自己释放;堆内存的原创 2014-09-19 22:11:44 · 27559 阅读 · 7 评论 -
使用JDK的javaagent机制时候,遇到的蛋疼无比的ClassNotFoundException
Premain-Class: net.aty.size.GetSizeAgent 类的全路径后面多了个空格,导致加载代理类的时候报了ClassNotFoundException原创 2014-06-10 22:17:37 · 7091 阅读 · 0 评论 -
java对象的内存布局(一):计算java对象占用的内存空间以及java object layout工具的使用
最近在学习java对象内存布局方面的一些知识,主要是想知道一个java对象到底占用多少内存空间,以及java对象在内存中到底是什么样子的。c/c++中的sizeof运算符能够方便地告诉我们一个变量占用的内存空间,但是在java中却没有直接提供这种机制。如果想获取java对象占用的内存大小,可以利用java的Instrumentation机制。在网上搜索的过程中看到了java object layout这个小工具,能够打印出类的布局信息。Java对象的内存布局:对象头(Header)、实例数据(Instanc原创 2015-06-09 20:19:00 · 11610 阅读 · 2 评论 -
(入门贴)JVM堆内存相关的启动参数:年轻代、老年代和永久代的内存分配
如果想观察JVM进程占用的堆内存,可以通过命令工具jmap或者可视化工具jvisualvm.exe。JVM这些启动参数都拥有默认值,如果想了解JVM的内存分配策略,最好手动设置这些启动参数。再通过JDK提供的工具的统计结果,就比较容易理解这些内存分配的理论知识。运行环境是win7 32位操作系统,JDK1.7.0_60版本。可以发现:堆内存、新生代内存、老年代内存、永久代内存,都有一个初始内存,还有一个最大内存。原创 2014-09-17 21:01:15 · 14810 阅读 · 1 评论 -
java对象的内存布局(二):利用sun.misc.Unsafe获取类字段的偏移地址和读取字段的值
我们利用JDK中的sun.misc.Unsafe来计算下字段的偏移地址,一则验证下之前文章中的结论,再则跟jol输出结果对比下。通过上面的几段代码,我们可以成功获取类中各个字段的偏移地址,这跟jol工具的输出结果和我们的结论是一致的。有了字段的偏移地址,在加上对象的起始地,我们就能够通过Unsafe直接获取字段的值了。原创 2015-06-10 11:33:34 · 6606 阅读 · 0 评论 -
java中虚引用PhantomReference与弱引用WeakReference(软引用SoftReference)的差别
本文主要是重申下这几种引用的差别,并给出实际的例子,让读者清楚的感受到它们的差别。软引用和弱引用差别不大,JVM都是先将其referent字段设置成null,之后将软引用或弱引用,加入到关联的引用队列中。我们可以认为JVM先回收堆对象占用的内存,然后才将软引用或弱引用加入到引用队列。而虚引用则不同,JVM不会自动将虚引用的referent字段设置成null,而是先保留堆对象的内存空间,直接将PhantomReference加入到关联的引用队列,也就是说如果我们不手动调用PhantomReference.cl原创 2014-11-21 21:57:17 · 4211 阅读 · 1 评论 -
使用spring-loaded开源项目,实现java程序和web应用的热部署
JDK1.5之后提供了java.lang.instrument.Instrumentation,即java agent机制能够实现类的redefinition和retransform。redefinition对应Instrumentation.redefineClasses()能够实现类的热替换,但遗憾的是功能很有限。最近遇到一个开源项目spring-loaded,看了下官方的介绍文档:发现它功能比JDK自带的强大多了。经过自己的尝试,发现使用spring-loaded项目,确实可以实现java应用的热部署原创 2014-11-03 20:36:28 · 7004 阅读 · 1 评论 -
java中的4种reference的差别和使用场景(含理论、代码和执行结果)
我们知道java语言提供了4种引用类型:强引用、软引用(SoftReference)、弱引用(WeakReference)和幽灵引用(PhantomReference),与引用密切相关的,还有一个引用队列ReferenceQueue。引用和引用队列的关系,对于垃圾回收来说非常重要,学习垃圾回收机制,必须要先了解引用和引用队列的使用方法。本文主要参考网上的一些理论,同时配合自己的一些测试代码,更好的理解这些概念,也解决了之前博客中遗留的问题。原创 2014-09-21 18:31:28 · 13744 阅读 · 3 评论 -
JVM运行报错:GC overhead limit exceeded
今天在折腾OOM和java的4种引用类型的时候,在运行过程中JVM报了一个错误:java.lang.OutOfMemoryError: GC overhead limit exceeded 这个错误平时遇到的概率很少很少,今天无意中遇到了,这里做个记录。oracle/sun官网的解释是:The concurrent collector will throw an OutOfMe原创 2014-11-16 22:37:07 · 23231 阅读 · 0 评论 -
解决JVM启动报错:Unrecognized VM option '+HeapDumpOnOutOfMemeryError'
今天再搞一些OutOfMemery的相关知识探索,我想在JVM遇到OOM错误的时候,能够打印出heap dump,以便事后用Eclipse Memory Analyzer Tool(MAT)等内存分析工具分析内存的占用情况。我使用了JDK1.6.0_37和JDK1.7.0_60版本进行试验,到网上找了下,知道-XX:+HeapDumpOnOutOfMemoryError可以让JVM在探测到内存OO原创 2014-11-16 20:51:41 · 17181 阅读 · 2 评论 -
jmap命令(Java Memory Map)的使用
jmap的使用可以参考:官方文档 http://docs.oracle.com/javase/6/docs/technotes/tools/share/jmap.html和这篇博客 http://blog.youkuaiyun.com/fenglibing/article/details/6411953本文主要是介绍一下jmap常用的几个参数,作为自己的备忘录。注意如果是使用64位的JVM,使用j原创 2014-09-17 12:59:37 · 2006 阅读 · 0 评论 -
使用JVM管理工具jvisualvm,系统提示"无法检测到本地java应用程序"的原因和解决办法
我使用的JDK版本是1.6.0_37版本,操作系统是windows xp,今天想使用下%JAVA_HOME%/bin/目录下的一些管理工具,结果遇到麻烦了。使用JPS命令,无法列出本地运行的java虚拟机;使用jvisualvm,提示"无法检测到本地java应用程序"。这个问题的原因可以看下:http://docs.oracle.com/javase/1.5.0/docs/guide/mana原创 2014-09-15 22:20:11 · 9723 阅读 · 0 评论 -
关于finalize机制和引用、引用队列的一些结论
C++有析构函数这个东西,能够很好地在对象销毁前做一些释放外部资源的工作,但是java没有。Object.finalize()提供了与析构函数类似的机制,但是它不安全、会导致严重的内存消耗和性能降低,应该避免使用。best practice是:像java类库的IO流、数据库连接、socket一样,提供显示的资源释放接口,程序员使用完这些资源后,必须要显示释放。所以可以忘记Object.finali原创 2014-09-22 16:46:54 · 3768 阅读 · 0 评论 -
文章汇总:关于java的finalize,引用和引用队列,自动释放系统外部资源的一些文章
之前写过一篇博客,关于非堆内存如何自动释放的,由此慢慢延伸写了几篇关于垃圾回收、finalize机制、引用和引用队列、sun.misc.Cleaner相关的文章,通过这几篇文章感觉自己收获很大了,对java垃圾回收相关的知识了解更深刻了。这篇博客主要做个汇总和简介,按照自己思路的延伸,把博客汇总下,方便大家阅读和查看。原创 2014-09-22 21:35:32 · 1946 阅读 · 0 评论 -
Effective Java Item7:Avoid Finalizers,解释为什么finalize是不安全的,不建议使用
在讨论如何回收堆外内存的时候,提到“NIO中direct memory的释放并不是通过finalize(),因为finalize不安全而且影响能”。Effective Java一书中也提到:Avoid Finalizers。人都有潜在的叛逆意识,别人给的结论或者制定的规范,除非有足够的理由说服你,除非懂得这么做背后的原因,否则只能是死记硬背,没有形象深入的理解,不能学到真正的东西。本文通过自己的理解和一些实际的例子,和大家一起更形象的理解finalize。还是那句经典的话“talking is cheap,原创 2014-09-21 15:38:03 · 5933 阅读 · 3 评论 -
使用sun.misc.Cleaner或者PhantomReference实现堆外内存的自动释放
之前的一篇博客:System.gc()和-XX:+DisableExplicitGC启动参数,以及DirectByteBuffer的内存释放 文章末尾处:提到java NIO包是通过sun.misc.Cleaner和PhantomReference来实现堆外内存的自动释放的。现在我们来学习下Cleaner和PhantomReference的使用,自己封装实现堆外内存的自动释放。sun.misc.Cleaner是JDK内部提供的用来释放非堆内存资源的API。 Cleaner.create()需要2个参数:第原创 2014-09-21 20:57:36 · 7395 阅读 · 0 评论 -
java中使用堆外内存,关于内存回收需要注意的事和没有解决的遗留问题(等大神解答)
JVM可以使用的内存分外2种:堆内存和堆外内存,堆内存完全由JVM负责分配和释放,如果程序没有缺陷代码导致内存泄露,那么就不会遇到java.lang.OutOfMemoryError这个错误。使用堆外内存,就是为了能直接分配和释放内存,提高效率。JDK5.0之后,代码中能直接操作本地内存的方式有2种:使用未公开的Unsafe和NIO包下ByteBuffer。C语言的内存分配和释放函数malloc/free,必须要一一对应,否则就会出现内存泄露或者是野指针的非法访问。java中我们需要手动释放获取的堆外内存吗原创 2014-09-16 21:43:52 · 18389 阅读 · 5 评论 -
JVM的动态agent机制:在main函数启动之后运行agent
premain时Java SE5开始就提供的代理方式,给了开发者诸多惊喜,不过也有些须不变,由于其必须在命令行指定代理jar,并且代理类必须在main方法前启动。因此,要 求开发者在应用前就必须确认代理的处理逻辑和参数内容等等原创 2014-09-02 22:31:06 · 10938 阅读 · 1 评论