Java程序要故意填充PermGen?

2024-04-13

当 PermGen 已满时,Glassfish 有时无法停止,在这种情况下asadmin stop-domain domain1不起作用。在 Glassfish 2.1.1 中,它会永远坐在那里;在 3.x 之后超时AS_ADMIN_READTIMEOUT。所以我现在正在编写 Glassfish 停止脚本,该脚本将在一定的超时后杀死/杀死 -9 它以确保它停止。

为了充分测试这一点,我需要重现这个 PermGen 完整场景。怎样才能故意填满PermGen呢?我目前正在使用 Java 1.7.0_45(如果有的话)。我已经编写了一个程序来填充堆,但这对我来说是一个新程序,我想我会转向SO。它需要是我可以部署到 GF 中的东西(.war?),这可能会更棘手(不确定)。感谢任何帮助,非常感谢。


我有东西给你。我不知道如何在这里上传 jar 文件,所以只是在这里添加文件。

方法:ClassGenerator 类在 while 循环中创建一个新的类加载器,并一遍又一遍地加载同一个类,直到用完 permgen。现在您会注意到有一个列表保存了已加载类的引用。这是为了防止 JVM 卸载这些类:)。

文件解释
第一张图显示,当您运行该程序时,它耗尽了永久代空间。如果您想在 Eclipse 中进行设置,第二张图显示了项目的结构。我在 eclipse 中测试了它,并将其导出为可运行的 jar 文件,它在两种情况下都有效。

Run as a runnable jar file and it ran out of permgen. Program ran out of permgen

Eclipse 项目设置

类生成器类

package com.vkg;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

public class ClassGenerator {
    private static final int BUFFER = 1024;
    private List<Class<?>> classList = new ArrayList<Class<?>>();

    public static void main(String[] args) {
        ClassGenerator classGenerator = new ClassGenerator();
        // Load just some class with class loaders until perm gen space fills.
        while (true) {
            classGenerator.classLoader();
        }
    }

    private void classLoader() {
        ClassLoader classLoader = new ClassLoader() {
            public Class<?> loadClass(String classNameWithPackage)
                    throws ClassNotFoundException {
                if (!classNameWithPackage.contains("DummyClass")) {
                    return super.loadClass(classNameWithPackage);
                }
                String className = classNameWithPackage.replace('.', '/')
                        + ".class";
                byte[] classData = null;
                InputStream inputStream = null;
                try {
                    inputStream = getResourceAsStream(className);
                    byte[] buffer = new byte[BUFFER];
                    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                    int bytesRead = -1;
                    while ((bytesRead = inputStream.read(buffer, 0, BUFFER)) != -1) {
                        outputStream.write(buffer, 0, bytesRead);
                    }
                    classData = outputStream.toByteArray();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    if (inputStream != null) {
                        try {
                            inputStream.close();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
                Class<?> c = defineClass(classNameWithPackage, classData, 0,
                        classData.length);
                resolveClass(c);
                System.out
                        .println("Steve I am loading another copy of Dummy class. Soon Permgen will fill.");
                classList.add(c);
                return c;
            }
        };

        try {
            Class.forName("com.vkg.DummyClass", true, classLoader);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

虚拟类。这可以是任何类。该类的唯一目的是多次加载。没有其他用途。此类中不执行任何逻辑。主要逻辑在ClassGenerator.java中

package com.vkg;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class DummyClass {
    public void classLoader() {
        ClassLoader classLoader = new ClassLoader() {
            public Class<?> loadClass(String classNameWithPackage) throws ClassNotFoundException {
                 if(!classNameWithPackage.contains("DummyClass")) {
                     return  super.loadClass(classNameWithPackage);
                 } 
                 String className = classNameWithPackage.replace('.', '/') + ".class";
                byte[] classData = null;
                try {
                    InputStream inputStream = getResourceAsStream(className);
                    byte[] buffer = new byte[1];
                    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                    int bytesRead = -1;
                    while ((bytesRead = inputStream.read(buffer, 0, 1)) != -1) {
                        outputStream.write(buffer, 0, bytesRead);
                    }
                    classData = outputStream.toByteArray();
                }
                catch (IOException e) {
                    e.printStackTrace();
                }

                Class<?> c = defineClass(classNameWithPackage, classData, 0, classData.length);
                resolveClass(c);
                System.out.println("Steve I am loading another copy of Dummy class. Soon Permgen will fill.");
                return c;
            }
        };

        try {
            Class.forName("com.vkg.DummyClass", true, classLoader);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

希望它可以帮助您测试服务器崩溃。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java程序要故意填充PermGen? 的相关文章

  • 为什么在使用 repaint() 而不是使用 getParent().repaint() 时会出现此 Swing 错误?

    这个问题是基于我不久前在一个简单的 Swing 骰子程序中遇到的问题 我发布的原始问题是here https stackoverflow com questions 22306637 mystery concurrency componen
  • 如何根据 JComboBox 选择动态地将控件添加到表单?

    我正在尝试使用 Swing 创建一个简单的 java 表单 这个想法的基本思想是用户将在 JComboBox 中选择 0 到 5 然后 通过 ItemStateChanged 侦听器 将动态添加几个面板 每个面板包含 4 个控件 因此 如果
  • Spring MVC 中的 CSRF(跨站请求伪造)保护

    我对春季的 CSRF 跨站请求伪造 保护有点困惑 不 我有我的 jsp 我的控制器和一个 Web 服务 我想要做的是在 Web 服务级别验证令牌 如果令牌匹配 则运行 Web 服务 在我的例子中执行数据库插入 JSP file
  • Spring boot 404错误自定义错误响应ReST

    我正在使用 Spring boot 来托管 REST API 即使浏览器正在访问 URL 以及自定义数据结构 我也希望始终发送 JSON 响应 而不是使用标准错误响应 我可以使用 ControllerAdvice 和 ExceptionHa
  • Java - 了解 PrintWriter 和刷新的需要

    好吧 首先我对所有代码表示歉意 但我觉得代码太多总比代码不够好 我正在制作一个简单的聊天客户端和印刷机 尤其是我正在努力解决的问题 使用现在的代码 它将与服务器类交互 并且完美地打印我想要打印的内容 但是 当我删除 writer flush
  • SimpleDateFormat 无法正确处理 DD

    我正在尝试获得这样的格式 2013 06 15 17 45 我在代码中执行以下操作 Date d new Date SimpleDateFormat ft new SimpleDateFormat YYYY MM DD HH mm Stri
  • 平衡括号问题的优化解

    给定一个仅包含字符的字符串 and 判断输入字符串是否有效 输入字符串在以下情况下有效 左括号必须由相同类型的括号封闭 左括号必须按正确的顺序关闭 请注意 空字符串也被视为有效 示例1 Input Output true Example 2
  • Hibernate、MySQL 视图和 hibernate.hbm2ddl.auto = 验证

    我可以在 Hibernate 中使用 MySQL 视图 将它们视为表 即 该实体与为表创建的实体没有什么不同 但是 当 Hibernate 设置为验证模型时 我的应用程序将不会部署 因为它找不到视图 因为它假设它是一个表 是否可以在启用部署
  • 酷还是傻? Catch(异常[NamingException, CreateException] e)

    我正在编写一些代码 我注意到异常处理中的一种模式让我思考 try do stuff throws JMS Create and NamingException catch NamingException e log1 e rollback
  • 在 JSF 自定义验证器中区分 ajax 请求和完整请求

    我的验证器需要知道它是完整请求还是 ajax 请求 在我当前的解决方案中 我检查 http 请求标头X Requested With元素 public void validate FacesContext context UICompone
  • 更改 Spring Web 应用程序的默认会话超时

    我必须测试一个由 spring 和 jsp 编写的 Web 应用程序 应用程序的默认会话超时为 30 分钟 我想减少会话超时 为此 我改变了web xml文件输入tomcatInstallationLocation conf 但这不起作用
  • 为什么 Casbah / Java MongoDB 驱动程序最终会出现 java.lang.IllegalArgumentException?

    我使用时看到一个奇怪的问题casbah java driver 当驱动程序尝试从 mongo 创建响应时 我不断遇到以下异常 Oct 16 2012 10 45 07 AM com mongodb DBTCPConnector MyPort
  • 未从线程接收位置数据

    我尝试使用计时器经常发送包含用户位置的短信 最初 我遇到了空指针异常 这是由于我犯了一个简单的错误 一旦解决了这个问题 一切似乎都运行良好 但是 它永远不会获取我的位置 因此 不断发送的文本显示 无法接收位置 我想问的是为什么它无法获取我的
  • Android 以编程方式停止 toast 通知?

    有没有办法以编程方式停止 Toast 消息 假设我有一个按钮 单击它可以滚动 toast 消息 并且在 onclick 事件中我想停止队列中的所有消息并只显示新消息 我该怎么做 我的代码的简化版本如下 代码 public class Hel
  • JavaFX 8 默认消息图标

    随着 JavaFX 的最近几次更新 我们收到了警报 我想获取消息的默认图标 错误 警告 在Swing中 我可以通过一些方式获取L F消息图标UIManager的属性 如何在 JavaFX 中获取消息的默认图标 它们是包含在属性中 还是由 C
  • 为什么我的 Java 路径中添加了“L”?

    我在我的类路径中加载了一个 jar 在 iReport 中 如果重要的话 我确信它具有所需的方法 但是当我尝试测试连接 从而调用该 jar 时 我得到一个 java lang NoSuchMethodError 说它正在引用班上 Lorg
  • JSF - 实施受限页面过滤器

    我正在关注 BalusC 的回答JSF 2 0 如何获取在浏览器地址栏中输入的 URL https stackoverflow com questions 4105263 jsf 2 0 how to get the url that is
  • 从 IntelliJ 运行 JavaFX 应用程序

    Versions openjdk版本 11 0 11 2021 04 20 OpenJDK 运行时环境 build 11 0 11 9 Ubuntu 0ubuntu2 20 10 OpenJDK 64 位服务器虚拟机 内部版本 11 0 1
  • JavaFX 中的 MVC 模式与场景生成器

    我是 JavaFX 新手 根据我当前的设置 正在努力创建合适的 MVC 架构 我使用 Scene Builder 单击了一个 UI 并指定了一个 Controller 类 Startup public class Portal extend
  • 使用 Spring Batch 将文件中的日期解析为 LocalDateTime

    我正在尝试使用 Spring Batch 读取包含日期的 CSV 文件 但在将日期解析为LocalDateTime Object 字段 日期 上的对象 目标 中的字段错误 拒绝值 2017 07 20 04 15 25 0 代码 typeM

随机推荐