加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

JAVA内存管理

发布时间:2020-12-15 07:45:37 所属栏目:Java 来源:网络整理
导读:set JAVA_OPTS=-server -Xms1024m -Xmx1024m -XX:PermSize=512M -XX:MaxPermSize=512m -XX:MaxNewSize=512M 虚拟机栈和本地方法栈溢出:StackOverflowError -Xoss:设置本地方法栈大

  set JAVA_OPTS=-server -Xms1024m -Xmx1024m -XX:PermSize=512M -XX:MaxPermSize=512m -XX:MaxNewSize=512M    虚拟机栈和本地方法栈溢出:StackOverflowError    -Xoss:设置本地方法栈大小    java堆溢出:OutOfMemoryError java heap space    -Xmx:设置虚拟机堆参数的最大值    -Xms:设置虚拟机堆参数的最小值    运行时常量池溢出:OutOfMemoryError PermGen space    -XX:PermSize ,-XX:MaxPermSize:限制方法区的大小    1.程序计数器    当前线程所执行的字节码的行号指示器    这类内存区域为“线程私有”的内存    此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域    2.Java虚拟机栈    这类内存区域为“线程私有”的内存    它的生命周期与线程相同。虚拟机栈描述的是Java 方法执行的内存模型:每个方法被执    行的时候都会同时创建一个栈帧(Stack Frame ①)用于存储局部变量表、操作栈、动态    链接、方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在    虚拟机栈中从入栈到出栈的过程。    3.本地方法栈    本地方法栈(NativeMethodStacks)与虚拟机栈所发挥的作用是非常相似的,其区别不过是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的Native方法服务。与虚拟机栈一样,本地方法栈区域也会抛出StackOverflowError和OutOfMemoryError异常    4.堆    垃圾回收的主要区域    是虚拟机所管理的内存中最大的一块,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存,但是随着JIT编译器的发展和逃逸分析技术逐渐成熟,栈上分配、标量替换优化技术将会导致一些微妙的变化发生,所有的对象都分配在堆上就变得不是那么绝对了。    5.方法区    方法区用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。    运行时常量池是方法区的一部分,用于存放编译器生成的各种字面量和符号引用。    标记清除算法    标记死亡和存活的类,然后清除掉。碎片化可能比较严重    复制算法    内存划分两部分,存活的移动到一边,然后另一边清除,吃内存    标记整理    存活的移动到一边,另一部分清理掉    分代回收算法    新生代用复制算法    老年代用标记清除、标记整理算法    1: /// <summary>    2: /// A program abstraction.    3: /// </summary>    4: public interface IHost : IDisposable    5: {    6: /// <summary>    7: /// The programs configured services.    8: /// </summary>    9: IServiceProvider Services { get; }    10:    11: /// <summary>    12: /// Start the program.    13: /// </summary>    14: /// <param name="cancellationToken">Used to abort program start.</param>    15: /// <returns>A <see cref="Task"/www.hongyaoyul.cn> that will be completed when the <see cref="IHost"/> starts.</returns>    16: Task StartAsync(CancellationToken cancellationToken = default);    17:    18: /// <summary>    19: /// Attempts to gracefully stop the program.    20: /// </summary>    21: /// <param name="cancellationToken">Used to indicate when stop should no longer be graceful.</param>    22: /// <returns>A <see cref="Task"/> that will be completed when the <see cref="IHost"/> stops.</returns>    23: Task StopAsync(CancellationToken cancellationToken = default);    24: }    该接口含有一个只读属性:IServiceProvider Services { get; },通过该属性,我们可以拿到所有Host初始化时所注入的对象信息。    IHostBuilder接口所承担的核心功能就是程序的初始化,通过:IHost Build()来完成,当然只需要运行一次即可。其初始化内容一般包括以下几个功能:    host3    另外需要说明的是,以上功能的初始化,是通过IHostBuilder提供的接口获取用户输入的信息后,通过调用Build()方法来完成初始化。以下为IHostBuilder的部分源代码:    1: /// <summary>    2: /// Set up the configuration for the builder itself. This will be used to initialize the <see cref="IHostEnvironment"/>    3: /// for use later in the build process. This can be called multiple times and the results will be additive.    4: /// </summary>    5: /// <param name="configureDelegate">The delegate for configuring the www.hnyxysy.com<see cref="IConfigurationBuilder"/> that will be used    6: /// to construct the <see cref="IConfiguration"/> for the host.</param>    7: /// <returns>The same instance of the <www.luqintang.com see cref="IHostBuilder"/> for chaining.</returns>    8: public IHostBuilder ConfigureHostConfiguration(Action<IConfigurationBuilder> configureDelegate)    9: {    10: _configureHostConfigActions.Add(configureDelegate ?? throw new ArgumentNullException(nameof(configureDelegate)));    11: return this;    12: }    13:    14: /// <summary>    15: /// Adds services to the container. This can be called multiple times and the results will be additive.    16: /// </summary>    17: /// <param name="configureDelegate">The delegate for configuring the <see cref="IConfigurationBuilder"/> that will be used    18: /// to construct the <see cref="IConfiguration"/> for the host.</param>    19: /// <returns>The same instance of the <see cref="IHostBuilder"/> for chaining.</returns>    20: public IHostBuilder ConfigureServices(Action<HostBuilderContext,IServiceCollection> configureDelegate)    21: {    22: _configureServicesActions.Add(configureDelegate ?? throw new ArgumentNullException(nameof(configureDelegate)));    23: return this;    24: }    25:    26: /// <summary>    27: /// Overrides the factory used to create the service provider.    28: /// </summary>    29: /// <typeparam name="TContainerBuilder">The type of the builder to create.</typeparam>    30: /// <param name="factory">A factory used for creating service providers.</param>    31: /// <returns>The same instance of the www.qiaoheibpt.com<see cref="IHostBuilder"/> for chaining.</returns>    32: public IHostBuilder UseServiceProviderFactory<TContainerBuilder>(IServiceProviderFactory<TContainerBuilder> factory)    33: {    34: _serviceProviderFactory = new ServiceFactoryAdapter<TContainerBuilder>(factory ?? throw new ArgumentNullException(nameof(factory)));    35: return this;    36: }    37:    38: /// <summary>    39: /// Enables configuring the instantiated dependency container. This can be called multiple times and    40: /// the results will be additive.    41: /// </summary>    42: /// <typeparam name="TContainerBuilder">The type of the builder to create.</typeparam>    43: /// <param name="configureDelegate">The delegate for configuring the <see cref="IConfigurationBuilder"/> that will be used    44: /// to construct the <see cref="IConfiguration"/> for the host.</param>    45: /// <returns>The same instance of the <see cref="IHostBuilder"/> for chaining.</returns>    46: public IHostBuilder ConfigureContainer<TContainerBuilder>(Action<HostBuilderContext,TContainerBuilder> configureDelegate)    47: {    48: _configureContainerActions.Add(new www.sanguoyoux.cn ConfigureContainerAdapter<TContainerBuilder>(configureDelegate    49: ?? throw new ArgumentNullException(nameof(configureDelegate))));    50: return this;    51: }    IHostService    文章开头有说过自定义Host Service对象,那么我们如何自定义呢,其实很简单只需要实现IHostService,并在ConfigureServices中调用services.AddHostedService<MyServiceA>()即可,以下是IHostService的源码:    1: /// <summary>    2: /// Defines methods for objects that are managed by the host.    3: /// </summary>    4: public interface IHostedService    5: {    6: /// <summary>    7: /// Triggered when the application host is ready to start the service.    8: /// </summary>    9: /// <param name="cancellationToken">Indicates that the start process has been aborted.</param>    10: Task StartAsync(CancellationToken cancellationToken);    11:    12: /// <summary>    13: /// Triggered when the application host is performing a graceful shutdown.    14: /// </summary>    15: /// <param name="cancellationToken">Indicates that the shutdown process should no longer be graceful.</param>    16: Task StopAsync(CancellationToken cancellationToken);    17: }    根据源码我们可以知道,该接口只有两个方法,即代码程序开始与停止的方法。具体的实现可以参考如下:    1: public class MyServiceA : IHostedService,IDisposable    2: {    3: private bool _stopping;    4: private Task _backgroundTask;    5:    6: public MyServiceA(ILoggerFactory loggerFactory)    7: {    8: Logger = loggerFactory.CreateLogger<MyServiceB>();    9: }    10:    11: public ILogger Logger { get; }    12:    13: public Task StartAsync(CancellationToken cancellationToken)    14: {    15: Logger.LogInformation("MyServiceB is starting.");    16: _backgroundTask = BackgroundTask(www.hongshengyl.cn);    17: return Task.CompletedTask;    18: }    19:    20: private async Task BackgroundTask()    21: {    22: while (!_stopping)    23: {    24: await Task.Delay(TimeSpan.FromSeconds(7));    25: Logger.LogInformation("MyServiceB is doing background work.");    26: }    27:    28: Logger.LogInformation("MyServiceB background task is stopping.");    29: }    30:    31: public async Task StopAsync(CancellationToken cancellationToken)    32: {    33: Logger.LogInformation(www.pingguoyul.cn"MyServiceB is stopping.");    34: _stopping = true;    35: if (_backgroundTask != null)    36: {    37: // TODO: cancellation    38: await _backgroundTask;    39: }    40: }    41:    42: public void Dispose()    43: {    44: Logger.LogInformation("MyServiceB is disposing.");    45: }    46: }    IHostService是我们自定义Host管理对象的入口,所有需要压入到Host托管的对象都必须要实现此接口。    Host生命周期的管理    该接口提供了一种我们可以在程序运行期间进行管理的功能,如程序的启动与停止事件的订阅,关于Host生命周期的管理,主要由IHostApplicationLifetime和IHostLifetime这两个接口来完成。    以下是IHostApplicationLifetime的源码?    1: public interface IHostApplicationLifetime    2: {    3: /// <summary>    4: /// Triggered when the application host has fully started.    5: /// </summary>    6: CancellationToken ApplicationStarted { get; }    7:    8: /// <summary>    9: /// Triggered when the application host is performing a graceful shutdown.    10: /// Shutdown will block until this event completes.    11: /// </summary>    12: CancellationToken ApplicationStopping { get; }    13:    14: /// <summary>    15: /// Triggered when the application host is performing a graceful shutdown.    16: /// Shutdown will block until this event completes.    17: /// </summary>    18: CancellationToken ApplicationStopped { get; }    19:    20: /// <summary>    21: /// Requests termination of the current application.    22: /// </summary>    23: void StopApplication(www.jintianxuesha.com);    24: }    IHostLifetime源码如下:    1: public interface IHostLifetime    2: {    3: /// <summary>    4: /// Called at the start of <see cref="IHost.StartAsync(CancellationToken)"/> which will wait until it‘s complete before    5: /// continuing. This can be used to delay startup until signaled by an external event.    6: /// </summary>    7: /// <param name="cancellationToken">Used to indicate when stop should no longer be graceful.</param>    8: /// <returns>A <see cref="Task"/>.</returns>    9: Task WaitForStartAsync(CancellationToken cancellationToken);    10:    11: /// <summary>http://jintianxuesha.com/?id=8    12: /// Called from <see cref="IHost.StopAsync(CancellationToken)"/> to indicate that the host is stopping and it‘s time to shut down.    13: /// </summary>    14: /// <param name="cancellationToken">Used to indicate when stop should no longer be graceful.</param>    15: /// <returns>A <see cref="Task"/>.</returns>    16: Task StopAsync(CancellationToken cancellationToken);    17: }    具体的使用可以参考如下代码:    1: public class MyLifetime : IHostLifetime,IDisposable    2: {    3: .........    4:    5: private IHostApplicationLifetime ApplicationLifetime { get; }    6:    7: public ConsoleLifetime(IHostApplicationLifetime applicationLifetime)    8: {    9: ApplicationLifetime = applicationLifetime ?? throw new ArgumentNullException(nameof(applicationLifetime));    10: }    11:    12: public Task WaitForStartAsync(CancellationToken cancellationToken)    13: {    14: _applicationStartedRegistration = ApplicationLifetime.ApplicationStarted.Register(state =>    15: {    16: ((ConsoleLifetime)state).OnApplicationStarted();    17: },    18: this);    19: _applicationStoppingRegistration = ApplicationLifetime.ApplicationStopping.Register(state =>    20: {    21: ((ConsoleLifetime)state).OnApplicationStopping();    22: },    23: this);    24:    25: .......    26:    27: return Task.CompletedTask;    28: }    29:    30: private void OnApplicationStarted()    31: {    32: Logger.LogInformation("Application started. Press Ctrl+C to shut down.");    33: Logger.LogInformation("Hosting environment: {envName}",Environment.EnvironmentName);    34: Logger.LogInformation("Content root path: {contentRoot}",Environment.ContentRootPath);    35: }    36:    37: private void OnApplicationStopping()    38: {    39: Logger.LogInformation("Application is shutting down...");    40: }    41:    42: ........    43: }    总结    至此,我们知道了创建Long Run Program所需要关注的几个点,分别是继承IHostService、订阅程序的生命周期时间以及Host的初始化过程。相对来说这段内容还是比较简单的,但是开发过程中,依然会遇到很多的问题,比如任务的定时机制、消息的接入、以及程序的性能优化等等,这些都需要我们在实践中进一步总结完善。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读