java内存分析
‘壹’ java 怎么分析内存哪里能看到对象的所有属性和方法
你的思考已经深入到了JVM的内部如何执行,看哪里的解说都不如官方文档来的可信,毕竟Java怎么执行还是Java官方说了算嘛。
所以我觉得,可以研读一下Java官方的JVM规范文档
Java虚拟机规范官方文档
‘贰’ 简述java内存分配与回收策率有什么用
引言:大多数情况下,对象在新生代Eden区中分配。当Eden区没有足够空间进行分配时,虚拟机将发起一次Minor GC。新生代GC(Minor GC):指发生在新生代的垃圾收集动作,因为Java对象大多都具备朝生夕灭的特性,所以Minor GC非常频繁,一般回收速度也比较快。老年代GC(Major GC / Full GC):指发生在老年代的GC,出现了Major GC,经常会伴有至少一次的Minor GC(但非绝对的,在Parallel Scavenge收集器的收集策略里就有直接进行Major GC的策略选择过程)。Major GC的速度一般会比Minor GC慢10倍以上。
三、总结
可达性分析:以名为“GC根”的对象为起点,从这些节点向下搜索。当一个对象不能连接到“垃圾回收根”时,意味着它是可回收的。
‘叁’ 如何排查Java内存泄露
1.打开/tomcat_home/bin/catalina.bat文件
2.加上:set JAVA_OPTS=%JAVA_OPTS% -server -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:heapmp,这样当内存溢出是就会在对应路径下生成mp文件
‘肆’ 学习JAVA一定要学内存分析吗
介个。。。额。。。怎么说呢。。。内存管理是程序设计中非常核心的知识,有了这部分知识你才能更好的编程。当然,如果你能通过记忆把编程的方法记住,不懂也没事。
个人觉得理解了内存管理的知识可以更好的进行程序设计。。。虽然是有点枯燥和错综复杂,但只要你听课或者看书的时候,拿着草稿纸画一下就会明白。
SE是非常重要的部分,也是Java的基础部分,好好学吧。。。既然选择了编程,就好好接受他的一切。
堆栈的东西,也就是个引用和实体的关系。。。。很简单的~~
加油~~~
‘伍’ Java 从内存剖析多态性
变量在类加载的时候开始初始化,肯定是父类变量先进入内存
方法调用时先从本类寻找,寻找不到再从父类寻找,本类同名方法进去内存,父类同名方法就不会进入内存,所以就覆盖了
‘陆’ JAVA栈和堆的内存分配,画出内存分析图!
第一个
请记住一点,String类只要赋值了,就永远无法改变其值,就算使用引用传递得到其表象的值变化,也只是指向的变化,如Stringstr1=“Hello”,str2=“World”;Stringstr1=str1+str2,最终结果是str1输出的确实是“HelloWorld”,但是str1还是为“Hello”
第二个
此时引用传递的是类属性,其内存变化如下
‘柒’ 如何分析java的内存占用情况
hi:
虚拟机的内存情况查看,使用Runtime类进行。如下:
//虚拟机内存使用量查询
class RamRun implements Runnable{
private Runtime runtime;
public void run(){
try{
runtime=Runtime.getRuntime();
System.out.println("处理器的数目"+runtime.availableProcessors());
System.out.println("空闲内存量:"+runtime.freeMemory()/ 1024L/1024L + "M av");
System.out.println("使用的最大内存量:"+runtime.maxMemory()/ 1024L/1024L + "M av");
System.out.println("内存总量:"+runtime.totalMemory()/ 1024L/1024L + "M av");
}catch(Exception e){
e.printStackTrace();
}
}
}
‘捌’ 详解Java语言中内存泄漏及如何检测问题 (1)
一般来说内存泄漏有两种情况。一种情况,在堆中的分配的内存,在没有将其释放掉的时候,就将所有能访问这块内存的方式都删掉(如指针重新赋值);另一种情况则是在内存对象明明已经不需要的时候,还仍然保留着这块内存和它的访问方式(引用)。第一种情况,在Java中已经由于垃圾回收机制的引入,得到了很好的解决。所以,Java中的内存泄漏,主要指的是第二种情况。
可能光说概念太抽象了,大家可以看一下这样的例子:
1 Vector v=new Vector(10);
2 for (int i=1;i<100; i++){
3 Object o=new Object();
4 v.add(o);
5 o=null;
6 }
在这个例子中,代码栈中存在Vector对象的引用v和Object对象的引用o。在For循环中,我们不断的生成新的对象,然后将其添加到Vector对象中,之后将o引用置空。问题是当o引用被置空后,如果发生GC,我们创建的Object对象是否能够被GC回收呢?答案是否定的。因为,GC在跟踪代码栈中的引用时,会发现v引用,而继续往下跟踪,就会发现v引用指向的内存空间中又存在指向Object对象的引用。也就是说尽管o引用已经被置空,但是Object对象仍然存在其他的引用,是可以被访问到的,所以GC无法将其释放掉。如果在此循环之后,Object对象对程序已经没有任何作用,那么我们就认为此Java程序发生了内存泄漏。
尽管对于C/C++中的内存泄露情况来说,Java内存泄露导致的破坏性小,除了少数情况会出现程序崩溃的情况外,大多数情况下程序仍然能正常运行。但是,在移动设备对于内存和CPU都有较严格的限制的情况下,Java的内存溢出会导致程序效率低下、占用大量不需要的内存等问题。这将导致整个机器性能变差,严重的也会引起抛出OutOfMemoryError,导致程序崩溃。
一般情况下内存泄漏的避免
在不涉及复杂数据结构的一般情况下,Java的内存泄露表现为一个内存对象的生命周期超出了程序需要它的时间长度。我们有时也将其称为“对象游离”。
例如:
1 public class FileSearch{
2
3 private byte[] content;
4 private File mFile;
5
6 public FileSearch(File file){
7 mFile = file;
8 }
9
10 public boolean hasString(String str){
11 int size = getFileSize(mFile);
12 content = new byte[size];
13 loadFile(mFile, content);
14
15 String s = new String(content);
16 return s.contains(str);
17 }
18 }
在这段代码中,FileSearch类中有一个函数hasString,用来判断文档中是否含有指定的字符串。流程是先将mFile加载到内存中,然后进行判断。但是,这里的问题是,将content声明为了实例变量,而不是本地变量。于是,在此函数返回之后,内存中仍然存在整个文件的数据。而很明显,这些数据我们后续是不再需要的,这就造成了内存的无故浪费。
要避免这种情况下的内存泄露,要求我们以C/C++的内存管理思维来管理自己分配的内存。第一,是在声明对象引用之前,明确内存对象的有效作用域。在一个函数内有效的内存对象,应该声明为local变量,与类实例生命周期相同的要声明为实例变量……以此类推。第二,在内存对象不再需要时,记得手动将其引用置空。
复杂数据结构中的内存泄露问题
在实际的项目中,我们经常用到一些较为复杂的数据结构用于缓存程序运行过程中需要的数据信息。有时,由于数据结构过于复杂,或者我们存在一些特殊的需求(例如,在内存允许的情况下,尽可能多的缓存信息来提高程序的运行速度等情况),我们很难对数据结构中数据的生命周期作出明确的界定。这个时候,我们可以使用Java中一种特殊的机制来达到防止内存泄露的目的。
之前我们介绍过,Java的GC机制是建立在跟踪内存的引用机制上的。而在此之前,我们所使用的引用都只是定义一个“Object o;”这样形式的。事实上,这只是Java引用机制中的一种默认情况,除此之外,还有其他的一些引用方式。通过使用这些特殊的引用机制,配合GC机制,就可以达到一些我们需要的效果。
‘玖’ 请教java堆外内存泄漏分析定位方法
对于基本类型,大家基本上没有异议,但是对于引用类型我们也不能有异议。
Java内存泄露情况
JVM回收算法 是很复杂的,我也不知道他们怎么实现的,但是我只知道他们要实现的就是:对于没有被引用的对象是可以回收的。所以你要造成内存泄露就要做到:
持有对无用对象的引用!
不要以为这个很轻易做到,既然无用,你怎么还会持有它的引用? 既然你还持有它,它怎么会是无用的呢?
以下以堆栈更经典这个经典的例子来剖析。
Java代码
public class Stack {
private Object[] elements=new Object[10];
private int size = 0;
public void push(Object e){
ensureCapacity();
elements[size++] = e;
}
‘拾’ 服务器Java虚拟机运行内存分析
总体来说也是正常的,内存总是有一个使用,回收而形成的波峰,波谷。而关于code cache这块,jvm现在是使用时加载,故而初始应用启用时会有一个较大的增长,随后会较平稳。
另外你当前项目内存使用比较小,随便使用-Xms 100m -Xmx100m调大到100M就可以解决大部分的问题。
如果你是想知道jconsole的各项说明要参考oracle的官方说明,那一个是比较清楚的。
如果你想知道的是如何分析内存使用,那就建议搜索下java gc log这个选项,使用HP jmeter这样的专业工具分析gc日志。