关于Java GC和我的堆栈实现链接列表
Posted
技术标签:
【中文标题】关于Java GC和我的堆栈实现链接列表【英文标题】:About Java GC and my stack implementation link list 【发布时间】:2020-12-11 10:36:44 【问题描述】:一天前我决定开始学习 Java。我选择实现堆栈(链表实现)和其他数据结构来学习它,但我不太确定我的代码,以及 Java GC 的行为,你们能检查我的代码是对还是错吗?
很抱歉,我不认识任何 Java 专家来询问我是否做对了。
顺便说一句,我来自 C 和 C++,我对我的程序占用的内存非常满意。
我尝试运行这个程序并推送了 500mb 的内存,然后当我使用 .pop() 方法时内存没有下降,我也等了大约 20 分钟,但没有任何反应。 我读到的是 java 会自动为我们释放内存,但由于我没有看到它出现故障,所以感觉好像我做错了。
我的堆栈
import java.util.Scanner;
// ------------------------ node ------------------------
class node<type>
type value;
node<type> prev;
node(type value)
this.value = value;
// for checking I guess
void recdisp(node<type> recurs)
if(recurs != null)
System.out.println(recurs.value);
recurs.recdisp(recurs.prev);
return;
// ------------------------ STACK ------------------------
class mystack<type>
node<type> top;
mystack(type value)
top = new node<type>(value);
top.prev = null;
void push(type value)
node<type> buffer = new node<type>(value);
buffer.prev = top;
top = buffer;
buffer = null;
type pop()
node<type> tmp;
if(top == null)
System.out.println("POP: Stack is Empty");
return null;
type pass = top.value;
tmp = top;
top = top.prev;
tmp = null;
return pass;
void peek()
System.out.println("TOP VALUE : "+top.value);
void display()
if(top != null)
top.recdisp(top);
else
System.out.println("Display: Stack is empty");
// ------------------------ MAIN CLASS ------------------------
public class myjava
public static void main(String []args)
mystack<Integer> stacks = new mystack<Integer>(5);
stacks.pop();
stacks.pop();
stacks.pop();
stacks.display();
stacks.push(10);
stacks.push(20);
stacks.push(30);
stacks.push(40);
stacks.display();
【问题讨论】:
您对内存“下降”的预期究竟如何? JVM 通常不会将分配的 RAM 返回给 OS,因为它猜测如果它需要 500MB 一次,它会再次需要它。 @chrylis -cautiouslyoptimistic 哦,我明白了,我在看我系统的内存,我以为我可以看到它下降了,但是我怎么能看到我的程序在 java 中的内存使用情况虚拟机?,我的代码也有问题吗? 【参考方案1】:好的,我现在已经知道如何正确监控我的java程序的内存了,我使用“jconsole”应用程序来监控JVM中分配的堆内存,但似乎我需要点击这个“请求垃圾”在它可以从我的堆栈中释放 .poped() 内存之前,我现在正在寻找一种方法来在我的 java 程序中执行此“请求垃圾收集”。
【讨论】:
你根本不需要'请求垃圾收集',JVM会自己决定什么时候需要垃圾收集(例如当它需要分配,但空间不足时) .何时执行取决于 Java 版本、选择的垃圾收集器及其配置。 正如马克所说,这样做是为了了解内存消耗,但在实际应用中既没有必要也不推荐; JVM 知道何时执行垃圾回收。【参考方案2】:这里涉及到几个概念。
JVM 为您的应用程序提供自动内存管理。与 C 不同,您不需要显式地为对象分配空间; JVM 将在堆中为您执行此操作。当您不再拥有对某个对象的任何引用时,它就有资格进行垃圾回收。重要的是要认识到,不能保证何时(或什至是否)收集对象。
大多数 GC 算法使用分代堆空间(将其分为年轻代和年老代)。您创建的几乎所有对象都只会在很短的时间内被引用。大部分对象都在年轻代收集,减少了老年代的负载。
直到最近,JVM 还不愿意将未使用的堆内存返回给操作系统。在 JDK 12 中,JEP 346 为 G1 收集器引入了即时内存释放。其他一些收藏家也做类似的事情,但不是全部。
根据您的问题,无法准确说出正在发生的事情。你没有说明你的堆有多大(或者你的机器有多少内存)。如果年轻代足够大,创建 500Mb 的数据甚至可能不会触发次要 GC 周期。此外,很大程度上取决于您使用的 JDK 版本。
【讨论】:
以上是关于关于Java GC和我的堆栈实现链接列表的主要内容,如果未能解决你的问题,请参考以下文章
在 python 中使用链表实现堆栈。 pop 方法的问题和关于可变性的问题