JAVA的堆栈和内存、垃圾回收解说
1.有关java健壮性特点的真相
很多书上都说java健壮性的特点是因为java使用数组代替了c++的指针;c++最令人头痛的问题就是内存问题,java的健壮性使编程人员不用再考虑内存的问题;这种观点和想法是不对,java虽然有垃圾回收机制,不需要程序员去delete内存,但是在编码的时候还是应该考虑到内存的,尽量不要去浪费jvm的内存;这里就涉及到了java的堆栈问题。
2.java堆栈的区别
堆:存放类类型,用new建立,垃圾自动回收机制负责回收,速度慢
1).堆是一个“运行时”数据区,类实例化对象是从堆上去分配空间的,也就是说堆上空间都是通过new指令建立的;
2).与c++的区别就是java不需要显示的去释放堆,而是由垃圾回收机制负责,这是因为堆是动态分配内存大小的,即程序运行的时候分配;
3).这也产生了一个问题,堆空间的数据内存读取比较慢。
例:String str =new String(“yangkai”);
栈:存放基本数据类型,速度快
1).栈主要存放基本数据类型(byte、short、int、long、float、double、boolean、char)和对象句柄;
2).数据可以共享;何为共享?这里说的共享不是程序员决定的而是由jvm来控制,指系统自动处理的方式,比如说:int a = 10;int b= 10;这里的a、b变量指向的栈上空间地址是同一个,这就是所谓的“数据共享”;jvm的处理逻辑:java虚拟机去处理int a = 10的时候先去栈上创建一个变量作为a的引用,然后去查栈去找有没有10的值,如果有就将a指向10,如果没有就把10存进来。
3).相对于堆来说速度快;
4).栈数据的大小与生存期是确定的,缺乏灵活性。
例:int a = 0;
3.实例化对象的方法
比如说String这个类的实例可以由两种方法建立:
String str = new String(“yangkai”);
String str = “yangkai”;
分析:这两个方式创建的额对象是不同的,依照咱们上面介绍的堆栈知识应该对这种String的实例有所了解了吧!第一种采用new方式的在堆上开辟空间没调用一次就会创建一个对象;第二种是现在栈上创建String对象的引用,然后存储“yangkai”再让str引用;下次再调用str,如果栈上有就不会再次创建了;所以一般比较String变量的时候都采用两种方式,equals()和“==”;一般“==”判断的是对象是否相等即是否是同一个对象;判断出来两个String对象相等了说明这个字符串是存放在栈的,数据是共享的,这两个字符串是同一个对象;而equals()判断两个对象的内容是否相等,比如判断堆上的字符串的内容只能通过equals()方法来判断,“==”判断的可能是false,因为每一个string在堆上都是以一个String对象存储的。
4.如何控制内存,这里教你查看jvm内存的使用
当前虚拟机的最大内存: Runtime.getRuntime().maxMemory();
循环前虚拟机已占内存: Runtime.getRuntime().totalMemory();
下面使用两个案例来监测jvm内存:
package com.hudong.memory;
/**
*
* @Title: MemoryTest.java
* @Copyright: Copyright (c)2005
* @Description: <br>
* <br>
* 测试java虚拟机的内存占用情况
* @Created on 2014-1-21 上午11:40:35
* @author杨凯
*/
public class MemoryTest { /**
* @param args
*/
public static void main(String[]args) {
testStringBuffer();
// testString();
} /**
* 测试String实例对象的占用的内存
*/
public static void testString() {
String str = new String("abcdefghijklmn");
int count = 0;
System.out.println("当前虚拟机的最大内存:" + Runtime.getRuntime().maxMemory()/ 1024 / 1024 + "m------" + Runtime.getRuntime().maxMemory()+ "byte");
System.out.println("循环前虚拟机已占内存:" + Runtime.getRuntime().totalMemory()/ 1024 / 1024 + "m====" + Runtime.getRuntime().totalMemory()+ "byte");
while (true) {
try {
str += str;
count++;
} catch (Error e) {
System.out.println("循环次数:" + count);
System.out.println("字符串循环后的大小为:" + str.length() / 1024 / 1024 + "m-=-=-=" + str.length() + "byte");
System.out.println("循环前虚拟机已占内存:" + Runtime.getRuntime().totalMemory()/ 1024 / 1024 + "m====" + Runtime.getRuntime().totalMemory()+ "byte");
System.out.println("遇到错误:" + e);
break;
}
}
/*
* 运行结果:
* 当前虚拟机的最大内存:793m------832438272byte
循环前虚拟机已占内存:127m====133234688byte
循环次数:23
字符串循环后的大小为:112m-=-=-=117440512byte
循环前虚拟机已占内存:642m====673669120byte
遇到错误:java.lang.OutOfMemoryError: Java heap space
*/
} /**
* 测试StringBuffer实例对象的占用的内存
*/
public static void testStringBuffer(){
StringBuffer sb = new StringBuffer("abcdefghijklmn");
int count = 0;
System.out.println("当前虚拟机的最大内存:" + Runtime.getRuntime().maxMemory()/ 1024 / 1024 + "m------" + Runtime.getRuntime().maxMemory()+ "byte");
System.out.println("循环前虚拟机已占内存:" + Runtime.getRuntime().totalMemory()/ 1024 / 1024 + "m====" + Runtime.getRuntime().totalMemory()+ "byte");
while (true) {
try {
sb.append(sb);
count++;
} catch (Error e) {
System.out.println("循环次数:" + count);
System.out.println("字符串循环后的大小为:" + sb.length() / 1024 / 1024 + "m-=-=-=" + sb.length() + "byte");
System.out.println("循环前虚拟机已占内存:" + Runtime.getRuntime().totalMemory()/ 1024 / 1024 + "m====" + Runtime.getRuntime().totalMemory()+ "byte");
System.out.println("遇到错误:" + e);
break;
}
}
/*
* 运行结果:
* 当前虚拟机的最大内存:793m------832438272byte
循环前虚拟机已占内存:127m====133234688byte
循环次数:23
字符串循环后的大小为:112m-=-=-=117440512byte
循环前虚拟机已占内存:539m====566108160byte
遇到错误:java.lang.OutOfMemoryError: Java heap space */
}
}
分析:以上两个程序用来说明String和StringBuffer两个占用内存的情况;其他资料上面介绍这两个类的使用的时候得出的结果是:Stringbuffer比String循环后得到的字符串字节大;而我在这测试的时候得到结果两个类得到的字符串大小是一样的,区别是耗费的额虚拟机的内存大小不一样,后者明显的比前者小。
注:安装完jdk之后jvm默认的大小是63m,上面我测试的时候是将jvm的配置文件的xmx大小调大之后的。
JAVA的堆栈和内存、垃圾回收解说的更多相关文章
- Java虚拟机学习笔记——JVM垃圾回收机制
Java虚拟机学习笔记——JVM垃圾回收机制 Java垃圾回收基于虚拟机的自动内存管理机制,我们不需要为每一个对象进行释放内存,不容易发生内存泄漏和内存溢出问题. 但是自动内存管理机制不是万能药,我们 ...
- Java内存垃圾回收机制(转贴)
Java的堆是一个运行时数据区,类的实例(对象)从中分配空间.Java虚拟机(JVM)的堆中储存着正在运行的应用程序所建立的所有对象,这些对象通 过new.newarray.anewarray和mul ...
- java 内存 垃圾回收调优
要了解Java垃圾收集机制,先理解JVM内存模式是非常重要的.今天我们将会了解JVM内存的各个部分.如何监控以及垃圾收集调优. Java(JVM)内存模型 正如你从上面的图片看到的,JVM内存被分成多 ...
- java内存垃圾回收模型
一.java的内存模型 介绍如下6个组成部分 1.程序计数器:一块较小内存区域,指向当前所执行的字节码.如果线程正在执行一个Java方法,这个计数器记录正在执行的虚拟机字节码指令的地址,如果执行的是N ...
- 牛客网Java刷题知识点之垃圾回收算法过程、哪些内存需要回收、被标记需要清除对象的自我救赎、对象将根据存活的时间被分为:年轻代、年老代(Old Generation)、永久代、垃圾回收器的分类
不多说,直接上干货! 首先,大家要搞清楚,java里的内存是怎么分配的.详细见 牛客网Java刷题知识点之内存的划分(寄存器.本地方法区.方法区.栈内存和堆内存) 哪些内存需要回收 其实,一般是对堆内 ...
- [Java] 理解JVM之三:垃圾回收机制
JVM内存中的各个区域都会回收吗? 首先我们知道 Java 栈和本地方法栈在方法执行完成后对应的栈帧就立刻出栈销毁,两者的回收率可以认为是100%:Java 堆中的对象在没有被引用后,即使用完成后会被 ...
- JAVA中堆栈和内存分配原理
1.栈.堆 1.寄存器:最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制.2. 栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量 ...
- JAVA中堆栈和内存分配
(一).栈.堆 1.寄存器:最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制. 2. 栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或 ...
- JVM值内存垃圾回收监控之jstat
如何判断JVM垃圾回收是否正常?一般的top指令基本上满足不了这样的需求,因为top主要监控的是总体的系统资源,很难定位到java应用程序. Jstat是JDK自带的一个轻量级小工具.全称“Java ...
随机推荐
- 十二星座 英文名:Aries 金牛座 (4/21 - 5/20)的英文名: Taurus 双子座 (5/21 - 6/21)的英文名: Gemini 巨蟹座 (6/22 - 7/22)的英文名: Cancer 狮子座 (7/23 - 8/22)的英文名: Leo 处女座/室女座 (8/23 - 9/22)的英文名: Virgo 天秤座 (9/2
十二星座的具体顺序是:白羊座(Aries).金牛座(Taurus).双子座(Gemini).巨蟹座(Cancer).狮子座(Leo).处女座(Virgo).天秤座(Libra).天蝎座(Scorpio ...
- MQL4编程—值传递和引用传递
定义 简单的说就是给一个变量或者对象取一个别名(引用和被引用的共享存储单元,要用修饰符&). 引用的用法 在MQL4中通过调试只接受引用作为函数参数的用法,在函数参数传递过程中,有两种传递方式 ...
- 业内首发 | 区块链数据服务 - BDS
区块链数据服务(Blockchain Data Service,BDS)是京东云区块链产品部发推出的,其将区块链的链式.非结构化数据通过技术手段进行结构化存储,实时同步到高性能数据仓库中. 用户可以通 ...
- 题解 P2981 【[USACO10FEB]奶牛在冰Cows on Ice】
楼上的思路都是从一个石头找跳到另一个石头的路径,但其实这题可以对于上下左右四个方向分别做一个虚拟节点,然后只需要找虚拟节点左边的虚拟节点就行了 问题是:不会用set怎么办??? 其实可以发现用vect ...
- java使用ZipOutputStream批量压缩文件,并将文件分别放置不同文件夹压缩
package cn.cnnho.backstage.controller;import java.util.ArrayList; import java.util.List; import java ...
- java实现图片和pdf添加铺满文字水印
依赖jar包 <!-- pdf start --> <dependency> <groupId>com.itextpdf</groupId> <a ...
- Java连接MySQL Warning: Establishing SSL connection without server's identity verification is not recommended
1. 数据库 1.1 创建表 在当前数据库students中,创建数据表student: mysql> create table student( ),#学生ID ),#学生姓名 -> a ...
- LaTeX Windows配置
1. 安装TeXstudio 用搜索引擎找合适的版本或者 在 https://sourceforge.net/projects/texstudio/ 下载 找合适的版本下载,点击下一步安装即可. Te ...
- ZJNU 2204 - dzj的数学作业
我猜这个数列可以直接从大到小凑…… 推出帕多瓦数列每一项,从大到小循环 遇到小于等于x的项就减掉这一项 全部循环完毕后判断x是否为0即可 #include<stdio.h> typedef ...
- mybatis自动扫描的时候,接口跟xml文件的名字最好能够一一对应
事实证明这是十分有好处的,当然,即便你不这么做,它也不一定会报invalid bound statement (not found),因为你不知道从哪儿拷来的配置文件可能从其他的地方做了配置,但是这么 ...