如何从内存中删除变量?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何从内存中删除变量?相关的知识,希望对你有一定的参考价值。

将文件转换为字节时,不应使用Files.readAllBytes类。使用不同的字节转换器之后。主要问题是无法从内存中删除变量中的字节数组。

示例1

byte[] x1=new byte[50];
x1=null; //not memory deleting;

示例2

byte[] x2=null;   //memory space:0
x2=new byte[50];  //memory space:50
x2=new byte[100]; //memory space:150
x2=new byte[10];  //memory space:160
x2=null;          //memory space:160

我意识到这是情况。

我们如何从内存空间清除此信息?有C语言(Malloc)的动态内存分配方法,该内存不会在Java中删除。

    package dragdrop;
import java.awt.EventQueue;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.TransferHandler;
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class gfgh {

private JFrame frame;
private File_Class file_Class=null;
private JPanel panel;

/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                gfgh window = new gfgh();
                window.frame.setVisible(true);              

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the application.
 */
public gfgh() {
    initialize();
}

/**
 * Initialize the contents of the frame.
 */
private void initialize() {
    frame = new JFrame();
    frame.setBounds(100, 100, 450, 300);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

     panel = new JPanel();
    panel.setBackground(Color.BLACK);
    frame.getContentPane().add(panel, BorderLayout.CENTER);

    JButton btnNewButton = new JButton("New button");
    btnNewButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {


            memorydelete();
        }
    });
    panel.add(btnNewButton);
    this.DragDrop(panel);

}

private  void DragDrop(JComponent component)
{
    @SuppressWarnings("serial")
    TransferHandler transferHandler=new TransferHandler(){

         @Override
         public boolean canImport(JComponent component,DataFlavor[] dataFlavor)
         {
             return true;
         }
         @SuppressWarnings("unchecked")
        @Override
        public boolean importData(JComponent comp, Transferable t) {
            // TODO Auto-generated method stub
             List<File> files;
            try {
                files =  (List<File>) t.getTransferData(DataFlavor.javaFileListFlavor);

                for(File file:files)
                 {
                     System.out.println(file.getAbsolutePath());
                     System.out.println(file.length());
                     file_Class=new File_Class();
                     //file read examle 1 false
                    //  file_Class.file=Files.readAllBytes(Paths.get(file.getAbsolutePath()));


                     //* file read example 2 false
                     /* 
                     RandomAccessFile f = new RandomAccessFile(file.getAbsolutePath(), "r");
                      file_Class.file = new byte[(int)f.length()];
                      f.readFully( file_Class.file);
                       */
                      //example 3  false
                    // file_Class.file=readFile(file);

                    //example 4  false
                     file_Class.file=readFile(file);
                     memorydelete();

                     ///////
                 }
                files=null;

                Runtime.getRuntime().gc();
            } catch (UnsupportedFlavorException e) {

                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

            return true;
        }
    };
    component.setTransferHandler(transferHandler);
}
public void memorydelete()
{
    file_Class.file=null;
    file_Class=null;
    Runtime.getRuntime().gc();
}
public static byte[] readFile(File file) throws IOException {
    // Open file
    RandomAccessFile f = new RandomAccessFile(file, "r");
    try {
        // Get and check length
        long longlength = f.length();
        int length = (int) longlength;
        if (length != longlength)
            throw new IOException("File size >= 2 GB");
        // Read file and return data
        byte[] data = new byte[length];
        f.readFully(data);
        return data;
    } finally {
        f.close();
    }
}
}
class File_Class {
public byte file[];
}
答案

在Java中,数组是对象。 Java垃圾收集器最终将处理它们,并将回收与未引用对象关联的内存。

您可以轻松地对此进行如下测试:

public class Test {
     public static void main(String[] args) {
        long m1 = Runtime.getRuntime().freeMemory();
        byte[] data = new byte[1024*1024*4];
        long m2 = Runtime.getRuntime().freeMemory();
        data = null;
        System.gc();
        long m3 = Runtime.getRuntime().freeMemory();
        System.out.println("m1: " + m1);
        System.out.println("m2: " + m2);
        System.out.println("m3: " + m3);
     }
}

输出(绝对值在您的环境中会有所不同):

m1: 15887208
m2: 11692888
m3: 15972272

如您所见,在这里明确触发垃圾回收将回收与4 MB字节数组关联的资源。现在,通常不需要显式地触发垃圾收集器,也不需要生产性/高效的(实际上没有保证可以触发垃圾收集器)。在示例中,此操作仅出于说明目的。

垃圾回收在后台运行,JVM对其进行调度以使其适合您。一种策略是在(几乎)耗尽堆空间时运行完整集合。事情变得更加复杂,因为不同代的对象通常存在不同种类的堆(例如,新对象与旧对象)。

您可以做的最重要的事情就是不要保留对未使用对象的引用。最终,那些未引用的对象将被收集,并且相关的内存将被重用。

另一答案

主要问题是变量中的字节数组无法从内存中删除。

没有那不是问题。

[您需要做的是通过将null分配给变量...以及其他仍可引用该数组的可到达变量,来安排字节数组不可访问。

垃圾收集器(GC)将处理它。

您无需致电System.gc()。 GC将在需要运行时运行。如果尝试干预,则可能只会使代码效率低下。


真正的问题是下列之一:

  1. 文件太大不能读入内存;即太大,您将获得一个OOME。如果是这种情况,解决方案是流式传输文件而不是使用readAllBytes

  2. 您对内存使用率感到困扰。内存很便宜。编程时间很昂贵。

  3. 如果确实

    需要

以最大程度地减少应用程序的内存使用,则说明您使用了错误的编程语言。 Java不是为这种编程风格而设计的。 Java和Java垃圾收集器的设计目的是在GC很少运行且有足够的可用内存在垃圾收集之间保留垃圾的情况下提高效率。如果您尝试解决此问题,则您的应用程序可能会浪费大量时间来回收少量内存。请注意,即使Java GC确实(几乎)立即收集了您无法访问的字节数组,它也可能不会将回收的内存返回给操作系统。因此,您的应用程序的内存占用空间不会减少。因此,您很可能不会从显式调用System.gc()中获得

any

真正的好处。
如果确实

需要

以最大程度地减少内存使用,请使用C或C ++
如果确实

需要

显式删除对象,请使用C或C ++

以上是关于如何从内存中删除变量?的主要内容,如果未能解决你的问题,请参考以下文章

如何查询/删除matlab 内存中的变量?

XSS:如何从 C# 中的字符串中删除 JS 片段?

如何使用Android片段管理器传递变量[重复]

如何从主要活动中替换片段

如何从一个片段中删除数据,这些片段应该反映在google firebase中的其他片段中

如何知道 Fragment 何时变得不可见