iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Java中内存安全问题的注意事项有哪些
  • 884
分享到

Java中内存安全问题的注意事项有哪些

2023-06-15 09:06:34 884人浏览 泡泡鱼
摘要

这篇文章给大家分享的是有关Java中内存安全问题的注意事项有哪些的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。前言Java在内存管理方面是要比C/C++更方便的,不需要为每一个对象编写释放内存的代码,JVM虚拟机

这篇文章给大家分享的是有关Java中内存安全问题的注意事项有哪些的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

前言

Java在内存管理方面是要比C/C++更方便的,不需要为每一个对象编写释放内存的代码,JVM虚拟机将为我们选择合适的时间释放内存空间,使得程序不容易出现内存泄漏和溢出的问题

不过,也正是因为Java把内存控制的权利交给了Java虚拟机,一旦出现内存泄漏和溢出方面的问题,如果不了解虚拟机是怎么使用内存的,那排查错误将会成为一项异常艰难的工作

下面先看看JVM如何管理内存的

内存管理

根据Java虚拟机规范(第3版) 的规定,Java虚拟机所管理的内存将会包括以下几个运行内存数据区域:

  • 线程隔离数据区:

    • 程序计数器: 当前线程所执行字节码的行号指示器

    • 虚拟机栈: 里面的元素叫栈帧,存储局部变量表、操作栈、动态链接、方法出口等,方法被调用到执行完成的过程对应一个栈帧在虚拟机栈中入栈到出栈的过程。

    • 本地方法栈: 和虚拟机栈的区别在于虚拟机栈为虚拟机执行Java方法,本地方法栈为虚拟机使用到的本地Native方法服务。

  • 线程共享数据区:

    • 方法区: 可以描述为堆的一个逻辑部分,或者说使用永久代来实现方法区。存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

    • 堆: 唯一目的就是存放对象的实例,是垃圾回收管理器的主要区域,分为Eden、From/To Survivor空间。

Java中内存安全问题的注意事项有哪些

Java各版本内存管理改进

下图中永久代理解为堆的逻辑区域,移除永久代的工作从jdk7就已经开始了,部分永久代中的数据(常量池)在JDK7中就已经转移到了堆中,JDK8中直接去除了永久代,方法区中的数据大部分被移到堆里面,还剩下一些元数据被保存在元空间里

Java中内存安全问题的注意事项有哪些

内存溢出

  • 内存泄露Memory Leak: 申请的内存空间没有及时释放,导致后续程序里这块内容永远被占用。

  • 内存溢出Out Of Memory: 要求的内存超过了系统所能提供的

运行时数据区域的常见异常

在JVM中,除了程序计数器外,虚拟机内存的其他几个运行时数据区域都有发生OOM异常的可能。

堆内存溢出

不断的创建对象,并且保证GC Roots到对象之间有可达路径来避免垃圾回收机制清除这些对象。

public class HeapOOM {    static class ObjectInHeap{    }    public static void main(String[] args) {        List<ObjectInHeap> list = new ArrayList();        while (true) {            list.add(new ObjectInHeap());        }    }}

栈溢出

单个线程下不断扩大栈的深度引起栈溢出。

public class StackSOF {    private int stackLength = 1;    public void stackLeak() {        stackLength++;        stackLeak();    }    public static void main(String[] args) {        StackSOF sof = new StackSOF();        try {            sof.stackLeak();        } catch (Throwable e) {            System.out.println("Stack Length: " + sof.stackLength);            throw e;        }    }}

循环的创建线程,达到最大栈容量。

public class StackOOM {    private void dontStop() {        while (true) {        }    }    public void stackLeadByThread() {        while (true) {            Thread thread = new Thread(new Runnable() {                @Override                public void run() {                    dontStop();                }            });            thread.start();        }    }    public static void main(String[] args) {        StackOOM stackOOM = new StackOOM();        stackOOM.stackLeadByThread();    }}

运行时常量池溢出

不断的在常量池中新建String,并且保持引用不释放。

public class RuntimeConstantPoolOOM {    public static void main(String[] args) {        // 使用List保持着常量池的引用,避免Full GC回收常量池        List<String> list = new ArrayList<String>();        int i = 0;        while (true) {            // intern()方法使String放入常量池            list.add(String.valueOf(i++).intern());        }    }}

方法区溢出

借助CGLib直接操作字节码运行时产生大量的动态类,最终撑爆内存导致方法区溢出。

public class MethodAreaOOM {    static class ObjectInMethod {    }    public static void main(final String[] args) {        // 借助CGLib实现        while (true) {            Enhancer enhancer = new Enhancer();            enhancer.setSuperclass(ObjectInMethod.class);            enhancer.setUseCache(false);            enhancer.setCallback(new MethodInterceptor() {                @Override                public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {                    return methodProxy.invokeSuper(o, objects);                }            });            enhancer.create();        }    }}

元空间溢出

助CG Lib运行时产生大量动态类,唯一的区别在于运行环境修改为Java 1.8,设置-XX:MaxMetaspaceSize参数,便可以收获java.lang.OutOfMemoryError: Metaspace这一报错

本机直接内存溢出

直接申请分配内存(实际上并没有真正向操作系统申请分配内存,而是通过计算得知内存无法分配,于是抛出异常)

public class DirectMemoryOOM {    private static final int _1MB = 1024 * 1024;    public static void main(String[] args) throws IllegalAccessException {        Field unsafeField = Unsafe.class.getDeclaredFields()[0];        unsafeField.setAccessible(true);        Unsafe unsafe = (Unsafe) unsafeField.get(null);        while (true) {            unsafe.allocateMemory(_1MB);        }    }}

常见案例

在工作中一般会遇到有以下几种情况导致内存问题

  • 传输数据量过大

因为传输数量过大、或一些极端情况导致代码中间结果对象数据量过大,过大的数据量撑爆内存

  • 查询出大量对象

这个多为sql语句设置问题,SQL未设置分页,用户一次查询数据量过大、频繁查询SQL导致内存堆积、或是未作判空处理导致WHERE条件为空查询出超大数据量等

  • 接口性能问题导致

这类为外部接口性能较慢,占用内存较大,并且短时间内高QPS导致的,导致服务内存不足,线程堆积或挂起进而出现FullGC

  • 元空间问题

使用了大量的反射代码,Java字节码存取器生成的类不断生成

问题排查

使用jmap分析内存泄漏

生成dump文件

jmap -dump:fORMat=b,file=/xx/xx/xx.hprof pid

dump文件下载到本地

dump文件分析

可以使用MAT,MAT可作为Eclipse插件或一个独立软件使用,MAT是一个高性能、具备丰富功能的Java堆内存分析工具,主要用来排查内存泄漏和内存浪费的问题。

使用MAT打开上一部后缀名.hprof的dump文件

Java中内存安全问题的注意事项有哪些

  • Histogram:直方图,各个类的实例,包括个数和大小,可以查看类引用和被引用的路径。

  • Dominator Tree:支配图,列出所有线程和线程下面的那些对象占用的空间。

  • Top Consumers:通过图形列出消耗内存多的实例。

  • Leak Suspects:MAT自动分析的内存泄漏报表

可以用这个工具分析出什么对象什么线程占用内存空间较大,对象是被什么引用的,线程内有哪些资源占用很高

以运行时常量池溢出为例

打开Histogram类实例表

Objects是类的对象的数量;Shallow是对象本身占用内存大小、不包含其他引用;

Retained是对象自己的Shallow加上直接或间接访问到对象的Shallow之和,也可以说是GC之后可以回收的内存总和

从图中可以看出运行时常量池溢出的情况,产生了大量的String和char[]实例

Java中内存安全问题的注意事项有哪些

在char[]上右键可以得到上图所有char[]对象的被引用路径,可以看出这些char数组都是以String的形式存在ArrayList中,并且是由main这个线程运行的

可以看出是main线程中新建了一个数组,其中存了32w+个长度为6的char数组组成的String造成的内存溢出

Java中内存安全问题的注意事项有哪些

感谢各位的阅读!关于“Java中内存安全问题的注意事项有哪些”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

--结束END--

本文标题: Java中内存安全问题的注意事项有哪些

本文链接: https://www.lsjlt.com/news/279351.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java中内存安全问题的注意事项有哪些
    这篇文章给大家分享的是有关Java中内存安全问题的注意事项有哪些的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。前言Java在内存管理方面是要比C/C++更方便的,不需要为每一个对象编写释放内存的代码,JVM虚拟机...
    99+
    2023-06-15
  • Java 内存安全问题的注意事项
    目录前言内存管理Java各版本内存管理改进内存溢出堆内存溢出栈溢出运行时常量池溢出方法区溢出元空间溢出本机直接内存溢出常见案例问题排查前言 Java在内存管理方面是要比C/C++更...
    99+
    2024-04-02
  • python切片中内存的注意事项有哪些
    这篇文章主要介绍了python切片中内存的注意事项有哪些,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1、由于 Python 列表的切片会在内存中创建新对象,因此需要注意的另...
    99+
    2023-06-20
  • java成员内部类的注意事项有哪些
    1. 成员内部类不能有静态成员(静态字段、静态方法),除非静态成员是final和static的常量。2. 成员内部类可以访问外部类的...
    99+
    2023-09-26
    java
  • java遍历的注意事项有哪些
    1. 确保正确设置起始条件和结束条件。2. 注意遍历顺序,遵循先进先出的原则。3. 确保遍历过程中不会出现越界或空指针异常。4. 遍...
    99+
    2023-09-27
    java
  • JavaEE内部类的注意事项有哪些
    本篇内容主要讲解“JavaEE内部类的注意事项有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“JavaEE内部类的注意事项有哪些”吧!前言内部类的设计也是一种封装的思想,封装体现的就是保护性...
    99+
    2023-07-05
  • Java集合注意事项有哪些
    今天小编给大家分享一下Java集合注意事项有哪些的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。一、Map 接口1、注意事项(...
    99+
    2023-06-30
  • C#中文件安全管理需要注意的事项有哪些
    这篇文章给大家分享的是有关C#中文件安全管理需要注意的事项有哪些的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一.DotNet文件目录常用操作:     &nbs...
    99+
    2023-06-14
  • PHP项目的各种问题以及注意事项有哪些呢
    PHP项目的各种问题以及注意事项有哪些呢,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。    弄了3年的p...
    99+
    2024-04-02
  • TokuDB安装及注意事项有哪些
    这篇文章将为大家详细讲解有关TokuDB安装及注意事项有哪些,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。TokuDB的特点:1、高压缩比,官方宣称可以达到1:12。2、...
    99+
    2024-04-02
  • hadoop3.x安装注意事项有哪些
    本篇内容介绍了“hadoop3.x安装注意事项有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!需要在环境变量中配置如下 hadoop_c...
    99+
    2023-06-02
  • java中守护线程的注意事项有哪些
    小编给大家分享一下java中守护线程的注意事项有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!java基本数据类型有哪些Java的基本数据类型分为:1、整数类...
    99+
    2023-06-14
  • Java中GuavaCache返回Null的注意事项有哪些
    本篇内容介绍了“Java中GuavaCache返回Null的注意事项有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Guava在实际的J...
    99+
    2023-06-25
  • jQuery.get的注意事项有哪些
    这篇文章主要讲解了“jQuery.get的注意事项有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“jQuery.get的注意事项有哪些”吧!   Ad...
    99+
    2024-04-02
  • Vue.js的注意事项有哪些
    这篇文章主要讲解了“Vue.js的注意事项有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Vue.js的注意事项有哪些”吧!1、为什么 Vue.js 不...
    99+
    2024-04-02
  • 安全第一:CMS 主题开发中的安全注意事项
    在 CMS 主题开发中,安全是最为重要的环节之一,它不仅关系到网站的正常运行,也关系到用户的数据安全和隐私。以下是一些 CMS 主题开发中的安全注意事项,希望能帮助您避免潜在的安全风险: 使用安全可靠的代码库和组件: 在开发 CM...
    99+
    2024-02-11
    CMS 主题开发 安全 注意事项 Web 开发
  • 美国服务器安全使用的注意事项有哪些
    美国服务器安全使用的注意事项:1.检查美国服务器的开放端口及防火墙,设置是否正常。2. 参考美国服务器的维护注意事项,完成基本的的流程操作。3. 使用美国服务器时关闭一些没必要的以及不用的服务。4. 不要轻易改动美国服务器的网卡,避免导致网...
    99+
    2024-04-02
  • spring事务的注意事项有哪些
    spring事务的注意事项有哪些,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。  事务一般是指数据库事务,是指作为一个程序执行单元执行的一...
    99+
    2024-04-02
  • Java需要注意的问题有哪些
    这篇文章主要介绍了Java需要注意的问题有哪些,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。Top 1:"abc"=="abc"返回的...
    99+
    2023-06-17
  • Java中的JavaScript路径打包:需要注意哪些安全问题?
    在Java开发中,经常需要使用JavaScript来实现前端的交互功能。而在Java中,为了方便管理和部署,我们通常会将JavaScript打包成一个文件,放在服务器上进行访问。但是,在进行路径打包时,需要注意一些安全问题,以避免出现潜在...
    99+
    2023-09-10
    打包 javascript path
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作