【Java】java的内存浅析

一.闲谈下

201407月记着那时候身体垮了下来,呵呵。想说,对自己的说,也是对大家的负责吧。那时候胸疼胸闷,然后几乎累垮了,我还坚持了一星期,那一星期真的迷迷糊糊。完全不能看代码,看代码就晕。一直想睡想睡。胸口会间接的疼一下。直到29号那晚饭后,我胸很闷。去旁边附一三甲医院检查,做了可怕的心电图。医院也是为人好,但是后面发生完全不可理喻。那时候的心情就像下面的图,当听到一个急诊不负责阿姨全科医生说“心电图有个波略高,赶紧24小时监护,立即联系家长”(她是不知道,我爸爸那时候也是 冠心病 发生期,他是不知道我根本没大碍被她这么折腾。我的心情会怎么样?医生为什么这么不会做人?虽然我在医科大学读书。)

现在慢慢的康复,其实没什么大病,熬夜熬多了,身子垮了。目前还是带着血药。stay with me 很多很多。我记着,我会感激。最大的是Home and 亲人。

告诉大家:

  1. 健康第一,革命的本钱。说说容易,做做难。(尽量规律点,不管你熬不熬夜)
  2. 还有保持乐观,这对自己对身体都很好
  3. 适量的运动
  4. 有些细节注意并尝试:泡脚….

二.正文

我想结合自己的故事,说实在有点伤感。但是我也不小心故意的,我只是想把这个故事传下去,我想你们会喜欢。在这里先谢谢了。就像每个在外的人,每个流浪在外学习也好,工作也好。家就像计算机里面的硬盘,想内存,有着你的家,家的地址。

穿越在城市的人呀,有时候驻足看看自己呀。

就像java,他是我的好朋友一样。java也有家,也有归宿。在java中,java程序,java虚拟机,操作系统。哪里都是它的归宿。它在其中彼此交互着。

下面一段话来自JAVA Bible 《Think in java》:

在JAVA中,有六个不同的地方可以存储数据:
1. 寄存器(register)。这是最快的存储区,因为它位于不同于其他存储区的地方——处理器内部。但是寄存器的数量极其有限,所以寄存器由编译器根据需求进行分配。你不能直接控制,也不能在程序中感觉到寄存器存在的任何迹象。
2. 堆栈(stack)。位于通用RAM中,但通过它的“堆栈指针”可以从处理器哪里获得支持。堆栈指针若向下移动,则分配新的内存;若向上移动,则释放那些内存。这是一种快速有效的分配存储方法,仅次于寄存器。创建程序时候,JAVA编译器必须知道存储在堆栈内所有数据的确切大小和生命周期,因为它必须生成相应的代码,以便上下移动堆栈指针。这一约束限制了程序的灵活性,所以虽然某些JAVA数据存储在堆栈中——特别是对象引用,但是JAVA对象不存储其中。海王星娱乐http://bct5453.com/
3. 堆(heap)。一种通用性的内存池(也存在于RAM中),用于存放所以的JAVA对象。堆不同于堆栈的好处是:编译器不需要知道要从堆里分配多少存储区域,也不必知道存储的数据在堆里存活多长时间。因此,在堆里分配存储有很大的灵活性。当你需要创建一个对象的时候,只需要new写一行简单的代码,当执行这行代码时,会自动在堆里进行存储分配。当然,为这种灵活性必须要付出相应的代码。用堆进行存储分配比用堆栈进行存储存储需要更多的时间。
4. 静态存储(static storage)。这里的“静态”是指“在固定的位置”。静态存储里存放程序运行时一直存在的数据。你可用关键字static来标识一个对象的特定元素是静态的,但JAVA对象本身从来不会存放在静态存储空间里。
5. 常量存储(constant storage)。常量值通常直接存放在程序代码内部,这样做是安全的,因为它们永远不会被改变。有时,在嵌入式系统中,常量本身会和其他部分分割离开,所以在这种情况下,可以选择将其放在ROM中
6. 非RAM存储。如果数据完全存活于程序之外,那么它可以不受程序的任何控制,在程序没有运行时也可以存在。

在我看来,我想分析的那块总结如下:

在java中,内存分析可分为Stack-栈 , Heap-堆(里面包含着方法区)等。栈灵活性不好,自动连续分配内存,后进先出。堆动态分配,灵活。所以java的家有这么些地方。

家是一把伞,帮我们遮风挡雨;家是心灵绿洲,带给我们快乐,排遣我们的烦恼;家是一盏灯,帮我们照亮前行之路。

一个洞也好,什么也好不如家的狗窝。善于电话打回家,一辈子也就这么短。

三.浅浅分析java内存

从一个小的代码里面说起吧。从小到大,慢慢让自己明白。

MainClass 程序的入口,像生活的道路一样。

public class MainClass
{
    public static void main(String[] args)
    {
        People dad = new People();
        dad.name = "Jeff Father";

        People mum = new People();
        mum.name = "Jeff Mum";

        Home home = new Home();
        home.address = "Place of freedom";

        home.dad = dad;
        home.mum = mum;

        home.mum.giveLove();
    }
}

下面对应的两个类 Home People

public class Home
{
    String address;

    People dad;

    People mum;
}

public class People
{
    String name;
    int age;

    public void giveLove()
    {
        System.out.println("give Love But Say Nothing!");
    }
}

Home family 写到这个类我想到了。那时候,24小时监护让我担心着。不敢跟父母说,因为那时候老爸还病着。就打给了在外地的姐姐,那时候真心苦笑着ing。但一直告诉自己“一切都会过去的。”

我很喜欢看动物世界,那里充满着love的瞬间。我也喜欢摄影。

运行后大家可以看到:(这是父母的爱)

“give Love But Say Nothing!”

首先要说的当着三个类被类加载器,类的代码信息放到了方法区。比如代码的属性,无参数或者带着参数的方法…如下图所示:

然后根据代码我们就把内存理一理。前面四句话,那是家里面可爱的爸爸妈妈,希望他们健健康康。当小的时候爸爸妈妈年轻,你也充满活力。我想到了《Tears in heaven》的那首歌:

People dad = new People();
dad.name = "Jeff Father";

People mum = new People();
mum.name = "Jeff Mum";

第一句话,首先new People()就在非方法区的堆里面,创造了属于这个new People的块,其方法giveLove指向了People类信息里面的具体方法。然后栈里面有对这个new出来的块一个引用 。

第二句话,首先 “Jeff Father”在MainClass类信息里面的常量池里面。上面new出来的块里面name对其常量一个引用。

家也是这样子的。家里面的地址是这辈子从小到大记得最清楚的地址。

Home home = new Home();

home.address = "Place of freedom";

以上代码和前面的一致。大家慢慢体会,待会给一张图会明白很多。

home.dad = dad;

home.mum = mum;

home里面的出现了一个people属性,它引用了dad那个块的id。就这样,家里面有了dad 有了mum才是家。家有什么好留恋。是个house,不是是亲人。 总结的图如下:

现在的自己,每天喝着中药。渐渐地进入了养生,健身的行列。发现了直到你靠近死亡的时候,你会感受到生命的价值,你就不会把价值往那些没用的地方去。

小的喂食,大的给食。无私是他们的天使职责。

下面有个小的练习题:如果在上面的MainClass main函数里加入如下的代码:

答案就不说了。哈哈

注意: == 表示数据引用相同是返回 true。

如果还不懂得话,可以根据我的图,和我下面的总结体会。

生命在于弄出点东西。我开始记备忘录,开始享受生活。开始新的一切。有时候和禅师说的很对,放下一些,去实践感受一下。受伤了就学会放下了。加油,大家。加油,我自己。最近我喜欢上了 C++ Java ,有自己的目标和理想。我觉得活的很踏实。姐姐的订婚日子也快到了,祝贺。我要学会smile。

四.感谢知识来源和小结

堆是一个运行时数据区,类的对象从中分配空间。这些对象通过new建立,它们不需要程序代码来显式的释放。java中的对象和数组都存放在堆中。堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。

方法区也是堆,存放着类的代码信息,static变量,常量池

栈中主要存放一些基本类型的变量(,int, short, long, byte, float, double, boolean, char)和对象引用。

参考资料:

google和自己的体会。

如以上文章或链接对你有帮助的话,别忘了在文章按钮或到页面右下角点击 “赞一个” 按钮哦。你也可以点击页面右边“分享”悬浮按钮哦,让更多的人阅读这篇文章。

http://www.cnblogs.com/Alandre/p/3928133.html

时间: 2024-10-25 09:46:09

【Java】java的内存浅析的相关文章

健康,home? [java的内存浅析]

健康,home? [java的内存浅析] 摘要: 原创出处: http://www.cnblogs.com/Alandre/ 泥沙砖瓦浆木匠 希望转载,保留摘要,谢谢! 乐观上上,how can other kno u,u r yourself!I must be strong and carry on. -泥沙砖瓦浆木匠 一.闲谈下 201407月记着那时候身体垮了下来,呵呵.想说,对自己的说,也是对大家的负责吧.那时候胸疼胸闷,然后几乎累垮了,我还坚持了一星期,那一星期真的迷迷糊糊.完全不能

Java中堆内存与栈内存分配浅析

Java把内存划分成两种:一种是栈内存,另一种是堆内存.在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配,当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java 会自动释放掉为该变量分配的内存空间,该内存空间可以立即被另作它用. 堆内存用来存放由 new 创建的对象和数组,在堆中分配的内存,由 Java 虚拟机的自动垃圾回收器来管理.在堆中产生了一个数组或者对象之后,还可以在栈中定义一个特殊的变量,让栈中的这个变量的取值等于数

java语言安全机制浅析

java通过所谓的沙箱安全模型保证了其安全性,下面我们就来看看java提供的安全沙箱机制. 组成沙箱的基本组件如下: 1.类装载器结构: 2.class文件检验器: 3.内置于java虚拟机(及语言)的安全特性: 4.安全管理器及java API. 一.类装载器体系结构 1.防止恶意代码去干涉善意的代码. 这是通过为不同类加载器提供不同的命名空间来实现的,在java虚拟机中,在同一个命名空间内的类可以直接进行交互,而不同的命名空间中类甚至不能觉察彼此的存在,除非显式地提供允许它们交互的机制. 2

容器中Java 程序OOMKilled原因浅析

背景: 业务的容器化刚刚搞完,线上开始告警,容器重启,容器重启.describe pod 查看原因是OOMKilled 分析: OOMKilled 是pod 中的进程使用的内存超过了.spec.containers[*].resources.limits.memory中定义的内存限制,在超出限制后, kubernetes 会向容器中的进程(pid=1)发送kill -9 信号.kill -9 信号对于进程来说是不可捕捉的,进程无法在收到-9 信号后优雅的退出. 这对于业务来说是有损的.那么为啥进

Java线程工作内存与主内存变量交换过程及volatile关键字理解

Java线程工作内存与主内存变量交换过程及volatile关键字理解 1. Java内存模型规定在多线程情况下,线程操作主内存变量,需要通过线程独有的工作内存拷贝主内存变量副本来进行.此处的所谓内存模型要区别于通常所说的虚拟机堆模型: 2. 线程独有的工作内存和进程内存(主内存)之间通过8中原子操作来实现,如下图所示: 原子操作的规则(部分): 1) read,load必须连续执行,但是不保证原子性. 2) store,write必须连续执行,但是不保证原子性. 3) 不能丢失变量最后一次ass

探讨深入Java虚拟机之内存优化

上一篇我们讲述了Java虚拟机的体系结构和内存模型,那么我们就不得不说到内存泄露.大家都知道,Java是从C++的基础上发展而来的,而C++程序的很大的一个问题就是内存泄露难以解决,尽管Java的JVM有一套自己的垃圾回收机制来回收内存,在大多数的情况下并不需要java程序开发人员操太多的心,但也是存在泄露问题的,只是比C++小一点.比如说,程序中存在被引用但无用的对象:程序引用了该对象,但后续不会或者不能再使用它,那么它占用的内存空间就浪费了. 我们先来看看GC是如何工作的:监控每一个对象的运

Java对象的内存布局

Java对象的内存布局:对象头(Header),实例数据(Instance Data),对齐填充(Padding):另外:不同的环境结果可能有差异,我所在的环境是HotSpot虚拟机,64位Windows. 对象头 对象头在32位系统上占用8bytes,64位系统上占用16bytes. System.out.println("sizeOf(new Object()) = " + sizeOf(new Object())); sizeOf(new Object()) = 16 实例数据

Java中的内存泄漏

[转]介绍Java中的内存泄漏 1. 什么是内存泄漏? 内存泄漏的定义:对象已经没有被应用程序使用,但是垃圾回收器没办法移除它们,因为还在被引用着. 要想理解这个定义,我们需要先了解一下对象在内存中的状态.下面的这张图就解释了什么是无用对象以及什么是未被引用对象. 2. 为什么会发生内存泄漏? 来先看看下面的例子,为什么会发生内存泄漏.下面这个例子中,A对象引用B对象,A对象的生命周期(t1-t4)比B对象的生命周期(t2-t3)长的多.当B对象没有被应用程序使用之后,A对象仍然在引用着B对象.

如何设置Docker容器中Java应用的内存限制

如果使用官方的Java镜像,或者基于Java镜像构建的Docker镜像,都可以通过传递 JAVA_OPTS 环境变量来轻松地设置JVM的内存参数.比如,对于官方Tomcat 镜像,我们可以执行下面命令来启动一个最大内存为512M的tomcat实例 docker run --rm -e JAVA_OPTS='-Xmx512m' tomcat:8 在日志中,我们可以清楚地发现设置已经生效 "Command line argument: -Xmx512m" 02-Apr-2016 12:46